Raw Data
Processing
At the end of data collection, we received 895 responses. Of these,
199 participants did not complete the main survey subscales. The
analysis is based on the remaining 696 responses for which the main
subscales were completed, which contained only a few missing values.
Several redundant variables were removed from the raw data. In addition,
some original categorical variables were recategorized to avoid sparse
groups and improve interpretability.
Missing Value
Imputation
To main this sample size, we use random imputation approach to fill
in the missing values. Since all multi-item sub-scales were measured
using a Likert scale, the scores follows a multinomial distribution. The
empirical distribution will be used in the random imputation to main the
probability distribution of the observed data. The following code
imputes the missing values in all multi-item subscales.
Imputation = function(DataName){
for (i in 1:(dim(DataName)[2])){
vec = as.vector(DataName[, i])
na.id = which(is.na(vec))
n0 = length(na.id)
prob0 = table(vec)/length(vec)
imput.val = NULL
for (j in 1:n0){
imput.val[j] = sample(1:length(prob0), size = 1, prob = prob0)
}
DataName[na.id, i] = imput.val
}
DataName
}
Reverse Scoring
Reverse scoring is a crucial data preparation step
for multi-item surveys where some items are worded in the opposite
direction to prevent response bias. After item-wise review of all
instruments along with statistical procedures of correlation and
confirmatory factor analysis (CFA), item 2 in the Self-efficacy
Instrument and all questions except items 5 and 7
in the Technology Instrument were negatively worded. The scores
of these items were reversed.
In addition, all questions regarding engagement and resource use were
reverse-worded, so their scores were reversed for the subsequent
analysis.
Sparse Category
Regrouping
Two variables need to be regrouped in the following: course level and
ethnicity.
- MathCourseLevel
- Math.I: MATQ30, MAT100, MAT101, MAT102,
- Math.II: MAT193, MAT104, MAT112, MAT113, MAT115,
MAT131
- Math.III: MAT143, MAT145, MAT151, MAT161
- Math.IV: MAT162-MAT480
- Stats: MAT121, MAT125, STA200
- Other: All courses not listed above
- Ethnicity
- White
- Black: Black and African American
- Asian
- Other: Native Hawaiian or Pacific Islander, Multiple
Ethnicity or Other, Prefer Not To Answer
- Learning Modalities
df_with_freq <- Comp.Modality %>%
rowwise() %>%
mutate(
freq_A = sum(c_across(MS.1:MS.12) == "1"),
freq_B = sum(c_across(MS.1:MS.12) == "2"),
freq_C = sum(c_across(MS.1:MS.12) == "3")
) %>%
ungroup()
###
df_with_freq$max_freq_col <- names(df_with_freq)[max.col(df_with_freq[, c("freq_A", "freq_B", "freq_C")]) + 1]
df_with_freq$max_freq_value <- apply(df_with_freq[, c("freq_A", "freq_B", "freq_C")], 1, max)
df_with_freq$modality <- ifelse(df_with_freq$max_freq_col=="MS.1", "Auditory",
ifelse(df_with_freq$max_freq_col=="MS.2", "Visual", "Kinesthetic"))
Exploratory Factor
Analysis (EFA) on Anxiety
The abbreviated mathematical anxiety (MA) instrument developed by
Hopko et al. (2003) is characterized by a two-factor structure that
divides into two subscales: mathematics evaluation anxiety (MEA) and
mathematics learning anxiety (MLA). The subsequent exploratory factor
analysis serves to validate this construct.
# Check correlations (visually)
n = dim(Comp.Anxiety[,-1])[1]
cor_matrix <- cor(Comp.Anxiety[,-1])
#corPlot(cor_matrix, upper = FALSE)
# Bartlett's Test of Sphericity (we want a significant p-value, p < .05)
cortest.bartlett(cor_matrix, n = n)
# KMO Measure of Sampling Adequacy (MSA) (We want overall MSA > 0.6, ideally > 0.8)
KMO(cor_matrix)
Bartlett’s test of sphericity produced a statistically significant
result (p < .001), confirming that the variables are sufficiently
correlated to proceed with factor analysis. The Kaiser-Meyer-Olkin (KMO)
Measure of Sampling Adequacy, with both overall and item-level values
exceeding 0.80, indicates that the data contain adequate common variance
to warrant factor analysis. Furthermore, the scree plot clearly
demonstrates the anticipated two-factor structure of the construct.
# Get eigenvalues
fa_result <- fa(Comp.Anxiety[,-1], nfactors = ncol(Comp.Anxiety[,-1]), rotate = "none")
eigenvalues <- fa_result$e.values
# Scree plot with horizontal line using shapes
scree_plot <- plot_ly(x = 1:length(eigenvalues), y = eigenvalues,
type = 'scatter', mode = 'lines+markers',
line = list(width = 3),
marker = list(size = 8)) %>%
layout(
title = "Scree Plot with Kaiser Criterion (Eigenvalue)",
xaxis = list(title = "Factor Number"),
yaxis = list(title = "Eigenvalue"),
shapes = list(
list(
type = "line",
x0 = 0,
x1 = length(eigenvalues),
y0 = 1,
y1 = 1,
line = list(color = "red", width = 2, dash = "dash")
)
),
annotations = list(
list(
x = length(eigenvalues) * 0.8,
y = 1.1,
text = "Kaiser Criterion (λ = 1)",
showarrow = FALSE,
font = list(color = "red")
)
),
margin = list(
t = 100, # Adjust this value to increase or decrease the top margin
b = 50,
l = 50,
r = 50)
)
scree_plot
Next, we perform EFA to identify the items of MEA and MLA through
factor loadings.
## two-factor aEFA
efa_2factor <- fa(Comp.Anxiety[,-1], nfactors = 2, rotate = "oblimin",
fm = "pa", scores = "regression")
# Create a clean loadings table
loadings_table <- fa.sort(efa_2factor$loadings[])
pander(loadings_table, digits = 2, cutoff = 0.3)
| AMAS.2 |
0.83 |
0.061 |
| AMAS.4 |
0.8 |
0.054 |
| AMAS.8 |
0.78 |
-0.13 |
| AMAS.5 |
0.56 |
0.12 |
| AMAS.3 |
-0.024 |
0.74 |
| AMAS.7 |
-0.059 |
0.71 |
| AMAS.6 |
0.045 |
0.69 |
| AMAS.9 |
0.13 |
0.64 |
| AMAS.1 |
0.013 |
0.5 |
As shown in the table above, items 2, 4, 5, and 8 load onto the
evaluation anxiety factor, whereas the remaining items load onto the
learning anxiety factor. Two distinct subscales will be established for
subsequent analyses.
Anxiety.mea <- Comp.Anxiety[, c("ID", "AMAS.2", "AMAS.4", "AMAS.5", "AMAS.8")]
Anxiety.mla <- Comp.Anxiety[, c("ID", "AMAS.1", "AMAS.3", "AMAS.6", "AMAS.7", "AMAS.9")]
Validation and
Reliability
The major multi-item instruments used in this study are
well-established and have been used in various published research. In
practice, the validity and reliability of such established instruments
must be confirmed before any statistical analysis. We next perform
reliability and validity analyses to warrant the credibility of the
overall survey design and the quality of the collected data.
Validity
Analysis
Validity of a multi-item survey instrument answers
the question: “Am I actually measuring what I intend to measure?” It’s
about the soundness of the interpretation of the scores. In
psychometrics, validity refers to the degree to which a
scale measures what it claims to measure. For a single-factor
instrument, this means all items are indicators of one underlying
construct such as maths anxiety, self-efficacy, engagement, etc. in this
comprehensive survey. The CFA has been used in survey research widely,
see Watson, et al (1988) and Marsh (1996).
Confirmatory Factor Analysis (CFA) is a powerful
statistical technique used to test a pre-specified theory about the
structure of your instrument. We use CFA to confirm that your
hypothesized single-factor model is consistent with the observed data.
It provides rigorous evidence for construct validity in a list of
conventional measures:
Factor Loadings are the standardized weights
from the Confirmatory Factor Analysis (CFA). The suggested guidelines
are:
- A loading magnitude greater than 0.5 indicates that
the item shares at least 25% of its variance with the latent factor. In
the following table, we report the minimum loading for each instrument
under the column
std.all.min.
- All loadings must be statistically significant (p < 0.05). We
report the maximum p-value for each instrument under the column
pval.max.
Standardized Root Mean Square Residual (SRMR)
measures the goodness-of-fit of the CFA model. It represents the average
standardized residual between the observed and predicted correlation
matrices. A lower value indicates a better fit, with a suggested cutoff
of less than 0.08.
Comparative Fit Index (CFI) is another
goodness-of-fit measure for the CFA. It compares the specified model to
a null (independence) model. A higher value indicates a better fit, with
a suggested cutoff of greater than 0.9.
Tucker-Lewis Index (TLI) also measures the
goodness-of-fit of the CFA. Its interpretation and usage are similar to
those of the CFI.
After some exploratory analysis, we dropped a few items from the
Technology Instrument and defined two sucscales of the initial resource
instruments: use of resource and student
engagement.
The final results on the struct validity measures are summarized in
the following table.
cfa.analysis <- function(dataset){
#dataset <- Comp.Anxiety
predictors <- names(dataset[, -1])
n0 <- length(predictors)
cfa.model <- paste("latent =~", paste(predictors, collapse = " + "))
cfa.fit <- cfa(cfa.model, data = dataset[, -1], estimator = "MLM")
results <- summary(cfa.fit, standardized = TRUE, fit.measures = TRUE, rsquare = TRUE)
std.all.min <- min(results$pe$std.lv[1:n0])
pval.max <- max(results$pe$pvalue[2:n0])
srmr <- results$fit["srmr"]
cfi <- results$fit["cfi"]
tli <- results$fit["tli"]
#rmsea <- results$fit["rmsea"]
cbind(std.all.min = std.all.min, pval.max = pval.max, srmr = srmr, cfi = cfi, tli = tli)
}
anxiety.mea.vlid <-cfa.analysis(Anxiety.mea)
anxiety.mla.vlid <-cfa.analysis(Anxiety.mla)
anxiety.vlid <-cfa.analysis(Comp.Anxiety)
efficacy.vlid <-cfa.analysis(Comp.SelfEfficacy)
tech.vlid <-cfa.analysis(Comp.Technology)
cooperative.vlid <-cfa.analysis(Comp.Cooporative)
deductive.vlid <-cfa.analysis(Comp.Deductive)
demo.vlid <-cfa.analysis(Comp.Demonstration)
inductive.vlid <-cfa.analysis(Comp.Inductive)
integrate.vlid <-cfa.analysis(Comp.Integrative)
lecture.vlid <-cfa.analysis(Comp.LectureType)
repetive.vlid <-cfa.analysis(Comp.Repetitive)
engage.vlid <-cfa.analysis(Comp.Engage)
resource.vlid <-cfa.analysis(Comp.Resource)
##
vlid.table <-rbind(anxiety.mea = anxiety.mea.vlid, anxiety.mla = anxiety.mla.vlid,
anxiety = anxiety.vlid, self.efficacy = efficacy.vlid,
technology = tech.vlid, cooperative = cooperative.vlid,
deductive = deductive.vlid, demonstration = demo.vlid,
inductive = inductive.vlid, integrate = integrate.vlid,
lecture = lecture.vlid, repetitive = repetive.vlid,
engage = engage.vlid, resource = resource.vlid)
row.name <- c("anxiety.mea", "anxiety.mla", "anxiety", "self.efficacy",
"technology", "cooperative",
"deductive", "demonstration", "inductive", "integrate",
"lecture", "repetitive", "engage", "resource")
col.name <- c("std.all.min", "pval.max", "srmr", "cfi", "tli")
rownames(vlid.table) <- row.name
colnames(vlid.table) <- col.name
pander(vlid.table)
| anxiety.mea |
0.7244 |
0 |
0.04544 |
0.9674 |
0.9021 |
| anxiety.mla |
0.4804 |
0 |
0.02092 |
0.9899 |
0.9798 |
| anxiety |
0.4166 |
0 |
0.08501 |
0.8152 |
0.7536 |
| self.efficacy |
0.4797 |
2.464e-06 |
2.169e-09 |
1 |
1 |
| technology |
0.5089 |
0 |
0.08141 |
0.8235 |
0.7731 |
| cooperative |
0.8847 |
0 |
0.04424 |
0.9337 |
0.8894 |
| deductive |
0.7555 |
0 |
0.04682 |
0.9462 |
0.9193 |
| demonstration |
0.7079 |
0 |
0.0375 |
0.9569 |
0.9353 |
| inductive |
0.7378 |
0 |
0.03004 |
0.9712 |
0.9568 |
| integrate |
0.487 |
0 |
0.05739 |
0.9157 |
0.8735 |
| lecture |
0.7208 |
0 |
0.02609 |
0.9776 |
0.9663 |
| repetitive |
0.5762 |
0 |
0.05573 |
0.9084 |
0.8627 |
| engage |
0.6855 |
0 |
5.435e-09 |
1 |
1 |
| resource |
0.4235 |
0 |
0.07786 |
0.865 |
0.5951 |
The construct validity of all multi-item instruments was assessed
using Confirmatory Factor Analysis (CFI). The results confirmed that
most scales meet established psychometric standards. The mojprity of the
key fit indices, including CFI and TLI, exceeded the recommended
threshold of 0.90, while the SRMR fell below the 0.08 cutoff, indicating
a good model fit. Furthermore, all factor loadings were statistically
significant (p < .05) and substantial in magnitude (exceeding 0.4),
demonstrating strong relationships between the items and their intended
latent constructs. In summary, the validity analysis confirms that the
instruments used in this study are robust and appropriate for measuring
their respective concepts.
Remarks: (1). The above validity measures based on
the items follow multi-variate normal distribution, This is a strong
assumption. The items in each instrument are not continous. This
influences some of the validity measure. (2). In practice, we can use
some descriptive approaches to visual check with assuming multi-variate
normality.
Relianbility
Analysis
Reliability of a multi-item survey instrument
answers the question: “If I measure the same thing multiple times, will
I get a consistent result?” It measures how well the items that are
supposed to measure the same construct hang together.
Internal Consistency is the most common assessment
for a survey administered once. It measures the degree to which items in
a scale are correlated with each other. Two well-known internal
consistency measures are Cronbach’s Alpha (Cronabck, 1951) and
McDonald’s Omega (1999). McDonald’s Omega is more
robust than Cronbach’s Alpha.
Cronbach’s Alpha and McDonald’s
Omega typically range from 0 to 1. The suggested cut-offs are
given below.
anxiety.mea.rel <- Reliability.fun(Anxiety.mea)
anxiety.mla.rel <- Reliability.fun(Anxiety.mla)
anxiety.rel <- Reliability.fun(Comp.Anxiety)
efficacy.rel <- Reliability.fun(Comp.SelfEfficacy)
tech.rel <- Reliability.fun(Comp.Technology)
cooperative.rel <- Reliability.fun(Comp.Cooporative)
deductive.rel <- Reliability.fun(Comp.Deductive)
demo.rel <- Reliability.fun(Comp.Demonstration)
inductive.rel <- Reliability.fun(Comp.Inductive)
integrate.rel <- Reliability.fun(Comp.Integrative)
lecture.rel <- Reliability.fun(Comp.LectureType)
repetive.rel <- Reliability.fun(Comp.Repetitive)
#after.rel <- Reliability.fun(Comp.AfterClass)
#in.class.rel <- Reliability.fun(Comp.InClass)
engage.rel <- Reliability.fun(Comp.Engage)
resource.rel <- Reliability.fun(Comp.Resource)
##
Rel.table <-rbind(anxiety.mea = anxiety.mea.rel, anxiety.mla = anxiety.mla.rel,
anxiety = anxiety.rel, self.efficacy = efficacy.rel,
technology = tech.rel, cooperative = cooperative.rel,
deductive = deductive.rel, demonstration = demo.rel,
inductive = inductive.rel, integrate = integrate.rel,
lecture = lecture.rel, repetitive = repetive.rel,
engage = engage.rel, resource = resource.rel)
row.name <- c("anxiety.mea", "anxiety.mla",
"anxiety", "self.efficacy", "technology", "cooperative",
"deductive", "demonstration", "inductive", "integrate",
"lecture", "repetitive", "engage", "resource")
col.name <- c("Cronbach alpha", "McDonald's Omega")
rownames(Rel.table) <- row.name
colnames(Rel.table) <- col.name
pander(Rel.table)
| anxiety.mea |
0.8413 |
0.846 |
| anxiety.mla |
0.802 |
0.8052 |
| anxiety |
0.8638 |
0.866 |
| self.efficacy |
0.6631 |
0.7165 |
| technology |
0.9261 |
0.9282 |
| cooperative |
0.8875 |
0.8875 |
| deductive |
0.8778 |
0.8788 |
| demonstration |
0.8821 |
0.8825 |
| inductive |
0.8899 |
0.8904 |
| integrate |
0.8276 |
0.8314 |
| lecture |
0.8992 |
0.9009 |
| repetitive |
0.8877 |
0.8891 |
| engage |
0.8349 |
0.8351 |
| resource |
0.7474 |
0.7518 |
We can see from the above table that all calculated coefficients
exceeded the recommended threshold of 0.7, indicating good reliability.
The results confirm that the instruments used in this study demonstrate
strong internal consistency, meaning the items within each scale
reliably measure the same underlying construct.
Composite Scoring
The core purpose of constructing multi-item surveys is to measure
complex concepts with greater accuracy, reliability, and depth than a
single question ever could. All instruments used in this study are based
on a single-factor construct using the Likert scales. The commonly used
methods for defining single index to capture the information of the
single-factor construct are classified in three categories
Summing the Raw
Likert Scores
The simplest approach is to sum the raw Likert scores into a
composite score that represents a single factor within the survey
construct. This method is valid provided that all questionnaire items
are equally important, as each captures a similar amount of information
about the underlying factor.
However, this approach is violated in several critical scenarios,
leading to a biased and unreliable composite score. For example,
Violation of Equal Importance: The core assumption is
that each item is a equally strong indicator of the construct. In
reality, items often have different levels of importance. Summing items
with high and low levels of importance equally gives undue weight to
weaker indicators, effectively diluting the composite score with noise
and reducing its validity.
FA Approach
Confirmatory Factor Analysis (CFA) is a very common and often
practical approach to validating survey instruments and create
(weighted) composite score. It is a distribution dependent statistical
method. However, it comes with a set of distinct some disadvantages
particularly the assumption of multi-variate normal distribution. Factor
loadings in CFA are estimated based on the maximum likelihood which is
defined based on multivariate normal distribution.
We have used CFA to validate the instrument. Since all instruments in
this study are single-factor constructs, we will calculate the single
composite score for each instrument using CFA.
PCA Approach
PCA is a distribution-free method which uses a mathematical
transformation (orthogonal rotation) to obtain a new coordinate system
such that the first new axis (Principal Component 1) points in the
direction of the maximum variance in the data. The second axis is
orthogonal to the first and points in the direction of the next greatest
variance, and so on. The new axes (components) are linear combinations
of the original variables. Consequently, a k-item instrument will
generate k principal components.
Although there debates on using PCA in psychometrics, the earliest
applications of PCA in survey research can be traced back to 1950s
(Stouffer et al., 1950; Cattell, 1952; Duncan, 19 ). The goal was
consistently the same as it is today: to uncover the simple, latent
structures that underlie the complex correlations among many observed
survey questions.
Adjusting Direction of
PCs
Principal Components (PCs) are new, uncorrelated axes, whereas Likert
scores are ordinal rating scales. When using PCs to represent these
rating scales, their direction must be aligned. A simple method to
determine if a PC’s direction needs to be reversed is to examine the
correlation coefficients between the naive composite average scores and
the PC scores. If the correlation is negative, the corresponding PC
should be reversed; otherwise, the default axis should be retained.
Composite Scoring Using The first Principal Component
(PC1)
This approach has been employed since the 1950s (e.g., Guttman, 1954;
Hirschberg & Standish, 1959; Duncan, 1961). The rationale for using
the first principal component is that it accounts for the maximum
variance in the data and constitutes a linear combination of all items.
Much like in confirmatory factor analysis (CFA), the first principal
component can be interpreted as a weighted average of individual item
scores.
Composite Scoring Using Weighted Average of Item Scores
Across All PCs: Doubly Weighted
Average
In many real-world datasets, the underlying constructs are inherently
multidimensional. Consequently, limiting the analysis to the first
principal component means discarding structured information captured by
subsequent components (PC2, PC3, etc.). A composite score that
integrates all significant components offers a more holistic and
accurate summary measure. The primary barrier to the widespread adoption
of this method is the challenge associated with interpreting the
composite index’s structure.
Composite Scores To
Be Created
We will generate four types of composite scores for each of the 11
instruments for the purpose of empirical comparison.
- avg: The average of the raw item scores.
- cfa: The extract confirmatory factor analysis (cfa)
score (all instruments are based on the single-factor construct).
- pca1: The first principal component scores.
- pca.wt: The weighted average of pca scores across
all principal components.
#####
scores = function(df, dn){
###############
# mean score
##############
df.mean <- rowMeans(df[, -1])
###########################
## single factor score
##########################
x.var <- names(df[, -1])
n0 <- length(x.var)
cfa.model <- paste("latent =~", paste(x.var, collapse = " + "))
cfa.fit <- cfa(cfa.model, data = df[, -1], estimator = "MLM")
composite.cfa <- lavPredict(cfa.fit)
##########################
# pca analysis
##########################
pca.mdl <- prcomp(df[,-1], scale = TRUE)
pca0 <- pca.mdl$x[, 1]
r0 = cor(pca0, df.mean)
if(r0 < 0) {
pca.all <- -pca.mdl$x
}else{
pca.all <- pca.mdl$x
}
first.pca = pca.all[,1]
##########################
# weighted pca score
##########################
var.explained <-((pca.mdl$sdev)^2) / sum((pca.mdl$sdev)^2) #
composite_weighted_pca <- as.matrix(pca.all) %*% (var.explained)
outdata <- as.data.frame(cbind(avg = df.mean,
pca1 = first.pca,
wt.pca = as.vector(composite_weighted_pca),
cfa = as.vector(composite.cfa)))
names(outdata) <- paste0(dn,".", names(outdata), sep = "")
outdata
}
###
Anxiety.mea.score = scores(Anxiety.mea, "Anxiety.mea")
Anxiety.mla.score = scores(Anxiety.mla, "Anxiety.mla")
Anxiety.score = scores(Comp.Anxiety, "Anxiety")
SelfEfficacy.score = scores(Comp.SelfEfficacy0, "SelfEfficacy")
Technology.score = scores(Comp.Technology, "Technology")
Cooporative.score = scores(Comp.Cooporative, "Cooporative")
Deductive.score = scores(Comp.Deductive, "Deductive")
Demonstration.score = scores(Comp.Demonstration, "Demonstration")
Inductive.score = scores(Comp.Inductive, "Inductive")
Integrative.score = scores(Comp.Integrative, "Integrative")
LectureType.score = scores(Comp.LectureType, "LectureType")
Repetitive.score = scores(Comp.Repetitive, "Repetitive")
Engage.score = scores(Comp.Engage, "Engage")
Resource.score = scores(Comp.Resource, "Resource")
##
finalDat <- cbind(demographics, Anxiety.score, Anxiety.mea.score,
Anxiety.mla.score, SelfEfficacy.score, Technology.score,
Cooporative.score, Deductive.score, Demonstration.score,Inductive.score,
Integrative.score, LectureType.score, Repetitive.score,
Engage.score, Resource.score)
Some Graphical
Exploration
We next explore the distributions of the created composite scores and
perform some empirical comparisons. The primary goal of this survey
study is to investigate factors that are associated with mathematics
anxiety (MA) levels. To this end, we also look the distributions each
individual items in the MA instrument.
Distributions of
Composite Scores
The following are distributions of four generated composite scores
across all instruments. The purpose is to examine the behaviors of these
composite scores, especially the doubly weighted composite score based
on the principal component analysis.
plotly.fun <- function(in.data){
in.avg <- density(in.data[,1])
in.pc1 <- density(in.data[,2])
in.pcw <- density(in.data[,3])
in.cfa <- density(in.data[, 4])
dat.name <- sub("\\..*", "",names(in.data)[1]) #sub( text)
# plot density curves
fig <- plot_ly(x = ~in.avg$x, y = ~in.avg$y,
type = 'scatter',
mode = 'lines',
name = 'avg',
fill = 'tozeroy') %>%
# adding more density curves
add_trace(x = ~in.pc1$x, y = ~in.pc1$y,
name = 'pca1',
fill = 'tozeroy') %>%
add_trace(x = ~in.pcw$x, y = ~in.pcw$y,
name = 'pca.wt',
fill = 'tozeroy') %>%
add_trace(x = ~in.cfa$x, y = ~in.cfa$y,
name = 'cfa',
fill = 'tozeroy') %>%
layout(xaxis = list(title = 'scores'),
yaxis = list(title = 'Density'),
#title = dat.name,
margin = list(
t = 100, # Adjust this value to increase or decrease the top margin
b = 50,
l = 50,
r = 50)
)
fig
}
####
in.anxiety.mea = final.anxiety.dat[, c( "Anxiety.mea.avg", "Anxiety.mea.pca1", "Anxiety.mea.wt.pca","Anxiety.mea.cfa")]
in.anxiety.mla = final.anxiety.dat[, c("Anxiety.mla.avg","Anxiety.mla.pca1", "Anxiety.mla.wt.pca","Anxiety.mla.cfa")]
###
in.anxiety = final.anxiety.dat[, c( "Anxiety.avg", "Anxiety.pca1", "Anxiety.wt.pca", "Anxiety.cfa")]
in.efficacy = final.anxiety.dat[, c( "SelfEfficacy.avg", "SelfEfficacy.pca1","SelfEfficacy.wt.pca","SelfEfficacy.cfa")]
in.technology = final.anxiety.dat[, c( "Technology.avg","Technology.pca1", "Technology.wt.pca","Technology.cfa")]
in.cooporative = final.anxiety.dat[, c("Cooporative.avg","Cooporative.pca1", "Cooporative.wt.pca","Cooporative.cfa")]
in.deductive = final.anxiety.dat[, c("Deductive.avg","Deductive.pca1","Deductive.wt.pca","Deductive.cfa")]
in.demonstration = final.anxiety.dat[, c("Demonstration.avg","Demonstration.pca1","Demonstration.wt.pca","Demonstration.cfa")]
in.inductive = final.anxiety.dat[, c( "Inductive.avg","Inductive.pca1","Inductive.wt.pca","Inductive.cfa")]
in.integrative = final.anxiety.dat[, c( "Integrative.avg", "Integrative.pca1","Integrative.wt.pca","Integrative.cfa")]
in.lectureType = final.anxiety.dat[, c( "LectureType.avg", "LectureType.pca1", "LectureType.wt.pca","LectureType.cfa")]
in.repetitive = final.anxiety.dat[, c( "Repetitive.avg", "Repetitive.pca1", "Repetitive.wt.pca","Repetitive.cfa")]
in.engage = final.anxiety.dat[, c( "Engage.avg", "Engage.pca1", "Engage.wt.pca","Engage.cfa")]
in.resource = final.anxiety.dat[, c( "Resource.avg", "Resource.pca1", "Resource.wt.pca", "Resource.cfa")]
p.mea <- plotly.fun(in.anxiety.mea)
p.mla <- plotly.fun(in.anxiety.mla)
# Arrange in 1x2 grid
subplot(p.mea, p.mla, nrows = 1, titleX = TRUE, titleY = TRUE, margin = 0.1) %>%
layout(
annotations = list(
list(x = 0.05, y = .99, text = "Anxiety.mea",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
list(x = 0.75, y = 0.99, text = "Anxiety.mla",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14))
),
showlegend = FALSE
)
p1 <- plotly.fun(in.anxiety)
p2 <- plotly.fun(in.efficacy)
p3 <- plotly.fun(in.technology)
p4 <- plotly.fun(in.cooporative)
# Arrange in 2x2 grid
subplot(p1, p2, p2, p4, nrows = 2, titleX = TRUE, titleY = TRUE, margin = 0.1) %>%
layout(
annotations = list(
list(x = 0.05, y = .99, text = "Anxiety",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
list(x = 0.75, y = 0.99, text = "Self-efficacy",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
list(x = 0.05, y = 0.4, text = "Technology",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
list(x = 0.75, y = 0.4, text = "Coorporative",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14))
),
showlegend = FALSE
)
p1 <- plotly.fun(in.deductive)
p2 <- plotly.fun(in.demonstration)
p3 <- plotly.fun(in.inductive)
p4 <- plotly.fun(in.integrative)
# Arrange in 2x2 grid
subplot(p1, p2, p2, p4, nrows = 2, titleX = TRUE, titleY = TRUE, margin = 0.1) %>%
layout(
annotations = list(
list(x = 0.05, y = .99, text = "Deductive",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
list(x = 0.75, y = 0.99, text = "Demonstrative",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
list(x = 0.05, y = 0.4, text = "Inductive",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
list(x = 0.75, y = 0.4, text = "Intergrative",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14))
),
showlegend = FALSE
)
p1 <- plotly.fun(in.lectureType)
p2 <- plotly.fun(in.repetitive)
p3 <- plotly.fun(in.engage)
p4 <- plotly.fun(in.resource)
# Arrange in 2x2 grid
subplot(p1, p2, p2, p4, nrows = 2, titleX = TRUE, titleY = TRUE, margin = 0.1) %>%
layout(
annotations = list(
list(x = 0.05, y = .99, text = "Lecture Type",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
list(x = 0.75, y = 0.99, text = "Repetative",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
list(x = 0.05, y = 0.4, text = "Engagement",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
list(x = 0.75, y = 0.4, text = "Resource",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14))
),
showlegend = FALSE
)
These density curves illustrate the distributions of the four
composite scores (avg, cfa, pc1, and
pca.wt) for all single-factor instruments in the
survey. The avg is a naive measure, derived from the
arithmetic mean of the item scores. The cfa and
pc1 composites are weighted averages, where the weights
(loadings) are derived from distinct latent variable models. The
pca.wt composite is a doubly
weighted average, based on both the original item scores
and all of the resulting principal components.
- Three model-based composite scores (cfa, pc1, and
pca.wt) are centered at 0 but exhibit different
behaviors:
- pc1 has the largest variance.
- cfa has the smallest variance.
- avg and pca.wt behave similarly,
differing primarily in their locations.
The composite score avg serves as a reference point,
analogous to an empirical distribution, as it uses all item scores
directly. In contrast, pca.wt uses a doubly weighted
average of all item scores without imposing complex distributional
assumptions. This demonstrates that pca.wt is a
reliable and robust composite score. For the remainder of this report,
the pca.wt score will be used, with
cfa occasionally employed for illustrative purposes for
some special cases.
Distribution of
Demographics
The distribution of demographic factors are reported in the following
figures.
# Enhanced hover information
Demographic.bar <-function(in.cat, varname){
freq.tbl <- table(in.cat)
df <- data.frame(
category <- names(freq.tbl),
values <- as.vector(freq.tbl)
)
# High-contrast colors (manually defined)
accessible_colors <- c(
'#D55E00', # Vermillion
'#0072B2', # Blue
'#F0E442', # Yellow
'#009E73', # Green
'#56B4E9', # Sky Blue
'#E69F00', # Orange
'#CC79A7' # Pink
)
fig <- plot_ly(df, x = ~category, y = ~values, type = 'bar',
hoverinfo = 'text',
text = ~paste('Category:', category, '<br>Value:', values, '<br>Percentage:', round(values/sum(values)*100, 1), '%'),
#text = ~paste("Value:", values),
textposition = 'auto',
marker = list(
color = accessible_colors[1:nrow(df)],
line = list(color = 'black', width = 2)
),
textfont = list(color = 'white', size = 12)) %>%
layout(
# title = list(text = varname,
# font = list(size = 18, color = 'black')),
xaxis = list(title = "Categories",
tickfont = list(color = 'black')),
yaxis = list(title = "Values",
gridcolor = 'lightgray',
tickfont = list(color = 'black')),
plot_bgcolor = 'white',
paper_bgcolor = 'white',
showlegend = FALSE,
margin = list(
t = 100, # Adjust this value to increase or decrease the top margin
b = 50,
l = 50,
r = 50)
)
fig
}
in.cat.sex <- final.anxiety.dat$sex
in.cat.race <- final.anxiety.dat$race
in.cat.class <- final.anxiety.dat$class
in.cat.major <- final.anxiety.dat$major
in.cat.math.level <- final.anxiety.dat$math.level
in.cat.modality <- final.anxiety.dat$modality
##
g.sex <- Demographic.bar(in.cat.sex, "Gender Distribution")
g.race <- Demographic.bar(in.cat.race, "Racial Distribution")
g.class <- Demographic.bar(in.cat.class, "Class Distribution")
g.major <- Demographic.bar(in.cat.major, "Major Distribution")
g.math.level <- Demographic.bar(in.cat.math.level, "Math Course Level")
g.modality <- Demographic.bar(in.cat.modality, "Learning Modality")
# Arrange in 2x2 grid
subplot(g.sex, g.race, g.class, g.major, nrows = 2, titleX = FALSE, titleY = TRUE, margin = 0.1) %>%
layout(
annotations = list(
list(x = 0.35, y = .99, text = "Gender",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
list(x = 0.75, y = 0.99, text = "Race",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
list(x = 0.35, y = 0.4, text = "Class Level",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
list(x = 0.75, y = 0.4, text = "Major",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14))
),
showlegend = FALSE
)
# Arrange in 2x2 grid
subplot(g.math.level, g.modality, nrows = 1, titleX = FALSE, titleY = TRUE, margin = 0.1) %>%
layout(
annotations = list(
list(x = 0.35, y = .99, text = "Math Course Level",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
list(x = 0.75, y = 0.99, text = "Learning Modality",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14))
),
showlegend = FALSE
)
Only one category in variable class is less than 3%
with 21 observations. Other variables don’t have issues on sparse
categories.
Relationship Between
Math Anxiety and Demographic Factors
A student’s demographic profile doesn’t determine their math anxiety,
but it significantly influences which type of anxiety they are most
vulnerable to and why. The next subsections present visual explorations
of the relationship between demographic factors and the two dimensions
of mathematical anxiety.
Mathematical
Evaluation Anxiety
This is the anxiety a student feels when their mathematical ability
is being formally or informally assessed. The primary fear is not of the
math itself, but of the negative consequences of performing poorly. It’s
performance-oriented. The stress comes from the situation of being
evaluated, not necessarily from the content.
## plotly for anxiety vs gender and other categorical demographic factor
gender.plotly <- function(in.var1, in.var2){
gender.anxiety <- plot_ly(final.anxiety.dat,
x = ~sex,
y = ~Anxiety.mea.wt.pca,
color = as.formula(paste0("~",in.var1)),
type = "box",
boxpoints = "no",
jitter = 0.3,
pointpos = 0,
hoverinfo = "y + x + name",
hovertext = ~paste("Group:", in.var1,
"<br>Factor:", sex,
"<br>Score:", round(Anxiety.mea.wt.pca, 2)),
marker = list(size = 5, opacity = 0.7)) %>%
layout(title = paste("Math Evaluation Anxiety (wt.PCA): Gender vs ", in.var2,""),
xaxis = list(title = ""),
yaxis = list(title = "Evaluation Anxiety Score"),
boxmode = "group",
hoverlabel = list(bgcolor = "white", font = list(size = 12)),
margin = list(
t = 100, # Adjust this value to increase or decrease the top margin
b = 50,
l = 50,
r = 50)
)
gender.anxiety
}
gender.math.level = gender.plotly("math.level", "Math Course Level")
gender.math.level
gender.race = gender.plotly("race", "Race")
gender.race
gender.class = gender.plotly("class", "Class")
gender.class
gender.major = gender.plotly("major", "Major")
gender.major
gender.modality = gender.plotly("modality", "Modality")
gender.modality
Some of the patterns observed in this study are consistent with the
existing literature.
- Female students have relatively higher evaluation anxiety level than
male students.
- The discrepancy of evaluation anxiety level across ethnic groups
also consistent with what reported in the existing literature.
Mathematical
Learning Anxiety
Mathematical learning anxiety stems directly from the subject matter,
where the primary source of distress is the act of engaging with
mathematical concepts. This engagement triggers an internal state of
confusion, frustration, and cognitive overload.
The next few figures examine the relationship between mathematical
learning anxiety and demographic factors, using the same visual approach
as we did for mathematical evaluation anxiety.
## plotly for anxiety vs gender and other categorical demographic factor
gender.plotly <- function(in.var1, in.var2){
gender.anxiety <- plot_ly(final.anxiety.dat,
x = ~sex,
y = ~Anxiety.mla.wt.pca,
color = as.formula(paste0("~",in.var1)),
type = "box",
boxpoints = "no",
jitter = 0.3,
pointpos = 0,
hoverinfo = "y + x + name",
hovertext = ~paste("Group:", in.var1,
"<br>Factor:", sex,
"<br>Score:", round(Anxiety.mla.wt.pca, 2)),
marker = list(size = 5, opacity = 0.7)) %>%
layout(title = paste("Math Learning Anxiety (wt.PCA): Gender vs ", in.var2,""),
xaxis = list(title = ""),
yaxis = list(title = "Learning Anxiety Score"),
boxmode = "group",
hoverlabel = list(bgcolor = "white", font = list(size = 12)),
margin = list(
t = 100, # Adjust this value to increase or decrease the top margin
b = 50,
l = 50,
r = 50)
)
gender.anxiety
}
gender.math.level.mla = gender.plotly("math.level", "Math Course Level")
gender.math.level.mla
gender.race.mla = gender.plotly("race", "Race")
gender.race.mla
gender.class.mla = gender.plotly("class", "Class")
gender.class.mla
gender.major.mla = gender.plotly("major", "Major")
gender.major.mla
gender.modality.mla = gender.plotly("modality", "Modality")
gender.modality.mla
The Gender Gap in
Evaluation and Learning Anxiety
It turns out that, comparing to math learning anxiety, evaluation
anxiety manifests the gender gap. This observation is supported by
academic research. The key insight is that the gender gap in math
performance is more strongly linked to the anxiety generated by the
testing situation than by anxiety toward the subject matter itself
(leading potential learning anxiety).
A robust body of evidence, from foundational meta-analyses (Hembree,
1990) to contemporary studies (Devine et al., 2012; Goetz et al., 2013),
establishes that female students experience disproportionately high
levels of math test anxiety—a factor more predictive of academic
outcomes than learning anxiety. This finding illuminates the work of
Else-Quest et al. (2010), demonstrating that the gender gap in math
performance is profoundly shaped by anxiety in evaluative environments.
Therefore, addressing the specific pressures of testing situations is
essential for closing this gap.
The following figure illustrates the relationship between gender and
the two types of math anxiety: learning anxiety and evaluation
anxiety.
mea0 <- final.anxiety.dat[, c("sex", "Anxiety.mea.wt.pca")]
mla0 <- final.anxiety.dat[, c("sex", "Anxiety.mla.wt.pca")]
names(mea0) = c("sex", "anxiety.score")
names(mla0) = c("sex", "anxiety.score")
mea.mla <- rbind(mea0, mla0)
anxiety.type <- c(rep("mea", dim(mea0)[1]), rep("mla", dim(mea0)[1]))
mea.mla$anxiety.type <- anxiety.type
####
df = na.omit(mea.mla)
# Create more complex grouped boxplot with statistical annotations
# Custom hover information
fig <- plot_ly(df,
x = ~anxiety.type,
y = ~anxiety.score,
color = ~sex,
type = "box",
hoverinfo = "y+x+name",
hovertemplate = paste(
"Gender: %{x}<br>",
"Anxiety Type: %{fullData.name}<br>",
"Anxiety Score: %{y:.2f}<br>",
"<extra></extra>"
)) %>%
layout(
title = "Gender Disparities in Math Evaluation and Learning Anxiety",
xaxis = list(title = ""),
yaxis = list(title = "Anxiety Score"),
boxmode = "group",
hoverlabel = list(bgcolor = "white", font = list(size = 12)),
margin = list( t = 100, # Adjust this value to increase or decrease the top margin
b = 50,
l = 50,
r = 50)
)
fig
Our results are also consistent with existing results in
literature.
Student Perceived
Teaching Strategies and Math Anxiety
Math anxiety is often exacerbated by a disconnect between a student’s
cognitive needs and the instructor’s predominant pedagogical approach.
To mitigate this, a proactive method involves leveraging students’
perceptions of teaching strategies.
Heatmap of Pairwise
Correlations
The following heatmap illustrates the pairwise correlations between
anxiety levels, student-perceived teaching strategies, and other
associated cognitive factors. A negative correlation between anxiety and
another composite score (shown in blue) indicates that anxiety decreases
as that composite score increases.
var.name <-c( "Anxiety.mea.wt.pca", "Anxiety.mla.wt.pca", "SelfEfficacy.wt.pca", "Technology.wt.pca",
"Cooporative.wt.pca", "Deductive.wt.pca", "Demonstration.wt.pca",
"Inductive.wt.pca", "Integrative.wt.pca", "LectureType.wt.pca",
"Repetitive.wt.pca", "Engage.wt.pca", "Resource.wt.pca")
all.composite.scores <- final.anxiety.dat[, var.name]
names(all.composite.scores) <- c( "Anxiety.mea", "Anxiety.mla", "SelfEfficacy", "Technology",
"Cooporative", "Deductive.", "Demonstration",
"Inductive", "Integrative", "LectureType",
"Repetitive", "Engage", "Resource.")
# Calculate correlation matrix
cor_matrix <- cor(all.composite.scores, use = "complete.obs")
# Convert to long format using melt
cor_long <- melt(cor_matrix)
names(cor_long) <- c("x", "y", "r")
# Remove self-correlations and upper triangle if desired
cor_long <- cor_long[cor_long$x != cor_long$y, ]
# Create interactive heatmap
plot_ly(cor_long, x = ~x, y = ~y, z = ~r, type = "heatmap",
colorscale = "RdBu", zmin = -1, zmax = 1,
hoverinfo = "text",
text = ~paste("X:", x, "<br>Y:", y, "<br>r =", round(r, 3))) %>%
layout(title = "Correlation Matrix",
xaxis = list(title = ""),
yaxis = list(title = ""),
margin = list(l = 100, r = 50, b = 100, t = 50))
The figure above shows that all perceived teaching strategies are
negatively correlated with both types of anxiety. In addition, students
with high levels of self-efficacy tend to have low levels of math
anxiety. Furthermore, the composite score for technology use is
negatively correlated with both learning and evaluation anxiety,
implying that technology can help reduce math anxiety. Conversely, we
also see that students who use more learning resources tend to have
higher learning anxiety.
As the red block in the center of the heatmap indicates, all teaching
strategies are positively correlated. This collinearity may pose a
problem for subsequent regression analysis. We will address this concern
in the following section.
Grouping Teaching
Strategies
The following density curves represent naive composite
scores derived from the average of item scores for each of the seven
teaching strategies. These curves illustrate the students’ perceptions
of their instructors’ teaching strategies. A higher score indicates that
students were more likely to perceive the use of that strategy.
var.name <-c( "Cooporative.avg", "Deductive.avg", "Demonstration.avg",
"Inductive.avg", "Integrative.avg", "LectureType.avg",
"Repetitive.avg")
all.composite.scores <- final.anxiety.dat[, var.name]
names(all.composite.scores) <- c("Cooperative", "Deductive", "Demonstrative",
"Inductive", "Integrative", "Lecture", "Repetitive")
# For older versions of tidyr
long_data <- all.composite.scores %>%
pivot_longer(
cols = c( Cooperative, Deductive, Demonstrative, Inductive, Integrative, Lecture, Repetitive), # Columns to reshape
names_to = "variable", # New column name for variable names
values_to = "value" # New column name for values
)
## Summarized stats
summary_stats <- long_data %>%
group_by(variable) %>%
summarise(
mean_val = mean(value),
median_val = median(value),
sd_val = sd(value),
n = n(),
.groups = 'drop'
)
# Create ridge plot with ggridges and convert to plotly
ridge_gg <- ggplot(long_data, aes(x = value, y = variable, fill = variable
)) +
geom_density_ridges(
alpha = 0.7,
scale = 2, # Adjust overlap
color = "white",
size = 0.5,
) +
scale_fill_brewer(palette = "Set1") +
#theme(plot.title = element_text(hjust = 0)) +
theme_ridges() +
labs(
title = "Distributions of Students' Perceived \n Teaching Strategy Indices",
x = "Perceived Teaching Strategy Score",
y = ""
) +
theme(legend.position = "none",
plot.title = element_text(hjust = 0.5),
plot.margin = margin(t = 1.2, unit = "cm"))
# Convert to plotly
ggplotly(ridge_gg)
As shown in the figure, the repetitive,
lecture-type, inductive, and
demonstrative approaches were perceived as more popular
than the integrative, deductive, and
cooperative approaches. This observation aligns with
the established classification of teaching styles in educational and
psychological research and classic textbooks.
| Deductive (Teacher provides rules and
examples: Joyce et al., 2015) |
Cooperative (Students work together:
Johnson, 2014) |
| Lecture Type (Teacher transmits
information: Brown,2007) |
Inductive (Students discover rules:
Bruner, 1961; Prince & Felder, 2006) |
| Demonstration (Teacher shows how:
Borich, 2017) |
Integrative (Students connect ideas:
Jacobs, 1989; Fogarty,1991) |
| Repetitive (Teacher drills the
information: Ormrod, 2020) |
|
The above classification is consistent with the one based on
cognitive demand (Bloom’s Taxonomy), which categorizes strategies as
requiring either lower-level thinking (remember, understand) or
higher-level thinking (apply, analyze, evaluate, create). T
This classification demonstrates a spectrum of pedagogical
approaches, from traditional, highly structured methods like Lecture and
Deductive teaching, to modern, student-driven methods like Inductive,
Cooperative, and Integrative learning. Demonstration and Repetitive
practice serve specific, often complementary, roles within this
spectrum.
Create Single
Composite Score for the Classification
We next define two single indices to represent the teaching
strategies based on the above classification. We conceptualize
teacher-centered and student-centered strategies as two single-factor
constructs. The indices are defined using a doubly weighted average of
the principal components. Following common practice, we report the
validity and reliability measures before calculating the composite
scores for the two classified teaching strategies.
Validity Measures
var.name <-c("Cooporative.cfa", "Deductive.cfa", "Demonstration.cfa",
"Inductive.cfa", "Integrative.cfa", "LectureType.cfa",
"Repetitive.cfa")
Stratege.wt.pca <- final.anxiety.dat[, var.name]
names(Stratege.wt.pca) <- c("Cooperative", "Deductive", "Demonstrative",
"Inductive", "Integrative", "Lecture", "Repetitive")
teacher0 <- Stratege.wt.pca[,c("Deductive", "Demonstrative", "Lecture", "Repetitive")]
student0 <- Stratege.wt.pca[,c("Cooperative", "Inductive", "Integrative", "Deductive")]
###
###
teacher.vlid <-cfa.analysis(teacher0)
student.vlid <-cfa.analysis(student0)
##
vlid.table <-rbind(teacher.ctrd = teacher.vlid, student.ctrd = student.vlid)
row.name <- c("teacher.ctrd", "student.ctrd")
rownames(vlid.table) <- row.name
colnames(vlid.table) <- c("std.all.min", "pval.max", "srmr", "cfi", "tli")
pander(vlid.table)
| teacher.ctrd |
0.5621 |
0 |
1.269e-08 |
1 |
1 |
| student.ctrd |
0.4867 |
0 |
1.006e-09 |
1 |
1 |
Reliability Measures
teacher <- Stratege.wt.pca[,c("Deductive", "Demonstrative", "Lecture", "Repetitive")]
student <- Stratege.wt.pca[,c("Cooperative", "Inductive", "Integrative")]
##
teacher.reliability <- Reliability.fun(teacher)
student.reliability <- Reliability.fun(student)
##
Rel.table <-rbind(teach = anxiety.mea.rel, anxiety.mla = anxiety.mla.rel)
row.name <- c("Teacher", "Student")
col.name <- c("Cronbach alpha", "McDonald's Omega")
rownames(Rel.table) <- row.name
colnames(Rel.table) <- col.name
pander(Rel.table)
| Teacher |
0.8413 |
0.846 |
| Student |
0.802 |
0.8052 |
The above goodness-of-fit and reliability measures exceed the
required thresholds of validity and reliability of an instrument. The
doubly weighted average of the original composite
scores of teaching strategies and appended to the analytic dataset.
######################################
#####
scores = function(df, dn){
###########################
## single factor score
##########################
x.var <- names(df)
n0 <- length(x.var)
cfa.model <- paste("latent =~", paste(x.var, collapse = " + "))
cfa.fit <- cfa(cfa.model, data = df, estimator = "MLM")
composite.cfa <- lavPredict(cfa.fit)
##########################
# pca analysis
##########################
pca.mdl <- prcomp(df, scale = TRUE)
pca0 <- pca.mdl$x[, 1]
r0 = cor(pca0, composite.cfa)
if(r0 < 0) {
pca.all <- -pca.mdl$x
}else{
pca.all <- pca.mdl$x
}
first.pca = pca.all[,1]
##########################
# weighted pca score
##########################
var.explained <-((pca.mdl$sdev)^2) / sum((pca.mdl$sdev)^2) #
composite_weighted_pca <- as.matrix(pca.all) %*% (var.explained)
outdata <- as.data.frame(cbind(pca1 = first.pca,
wt.pca = as.vector(composite_weighted_pca),
cfa = as.vector(composite.cfa)))
names(outdata) <- paste0(dn,".", names(outdata), sep = "")
outdata
}
###
teacher <- scores(teacher, "Teacher.ctrd")
student <- scores(student, "Student.ctrd")
Anxiety.Analytic.Data <- cbind(finalDat, teacher, student)
Structural Equation
Modeling Approach
Structural equation modeling (SEM) is a linear model
framework that models both simultaneous regression equations with latent
variables. Models such as linear regression, multivariate regression,
path analysis, confirmatory factor analysis, and structural regression
can be thought of as special cases of SEM. The following relationships
are possible in SEM:
- observed to observed variables (\(\gamma\), e.g., regression)
- latent to observed variables (\(\lambda\), e.g., confirmatory factor
analysis)
- latent to latent variables (\(\gamma, \beta\), e.g., structural
regression)
SEM uniquely encompasses both measurement and structural models. The
measurement model relates observed to latent variables and the
structural model relates latent to latent variables.
Notations and
Technical Terms in SEM
Some Technical Terms in SEM:
observed variable: a variable that exists in the
data, a.k.a item or manifest variable
latent variable: a variable that is constructed
and does not exist in the data
exogenous variable: an independent variable
either observed (x) or latent (\(\xi\))
that explains an endogenous variable
endogenous variable: a dependent variable,
either observed (y) or latent (\(\eta\)) that has a causal path leading to
it
measurement model: a model that links observed
variables with latent variables
indicator: an observed variable in a measurement
model (can be exogenous or endogenous)
factor: a latent variable defined by its
indicators (can be exogenous or endogenous)
loading: a path between an indicator and a
factor
structural model: a model that specifies causal
relationships among exogenous variables to endogenous variables (can be
observed or latent)
regression path: a path between exogenous and
endogenous variables (can be observed or latent)
SEM Path Model
A path model serves as the visual and mathematical blueprint for a
Structural Equation Model (SEM). This diagram employs a standardized
notation to represent hypothesized relationships between variables. The
specific model to be tested, which examines the complex structural
relationships between endogenous and exogenous variables, has the
following structure:
include_graphics("HypotheticalSEM.png")

To better understand the advantages and disadvantages of Structural
Equation Modeling (SEM) for analyzing complex relationships—such as
those between latent variables like math evaluation and learning
anxiety. we will briefly describe its mathematical formulation and MLE
of all model parameters using the above hypothetical SEM path model in
the appendix.
SEM
Implementation
We use the R lavaan library to implement the SEM to
assess the relationship between math evaluation, learning anxiety, and
related exogenous variables. The output presents results based on
standardized variables. The interpretation of the regression
coefficients is similar to that in a regular regression model,
indicating the change in the outcome (in standard deviations) for a
one-standard-deviation increase in a predictor.
Quick Reference of lavaan Syntax
~ predict, used for regression of observed outcome to
observed predictors (e.g., y ~ x)
1=~ indicator1, used for latent variable to observed
indicator in factor analysis measurement models (e.g.,
f =~ q + r + s)
- `
~~ covariance (e.g., x ~~ x)
~1 intercept or mean (e.g., x ~ 1
estimates the mean of variable x)
1* fixes parameter or loading to one (e.g.,
f =~ 1*q)
NA* frees parameter or loading (useful to override
default marker method, (e.g., f =~ NA*q)
a* labels the parameter ‘a’, used for model constraints
(e.g., f =~ a*q)
Anxiety.mea <- Comp.Anxiety[, c("AMAS.2", "AMAS.4", "AMAS.5", "AMAS.8")]
Anxiety.mla <- Comp.Anxiety[, c("AMAS.1", "AMAS.3", "AMAS.6", "AMAS.7", "AMAS.9")]
names(Anxiety.mea) <- c("MEA2", "MEA4", "MEA5", "MEA8")
names(Anxiety.mla) <- c("MLA1", "MLA3", "MLA6", "MLA7", "MLA9")
factor.names <- c("Technology.wt.pca", "SelfEfficacy.wt.pca", "Engage.wt.pca", "sex",
"Teacher.ctrd.wt.pca", "Student.ctrd.wt.pca", "Resource.wt.pca")
##
factor.var <- Anxiety.Analytic.Data[, factor.names]
names(factor.var) <- c("Tech", "Efficacy", "Engage", "gender",
"Teacher.ctrd", "Student.ctrd", "Resource")
### strategies var
stratgy.var <-c("Cooporative.wt.pca", "Deductive.wt.pca", "Demonstration.wt.pca", "Inductive.wt.pca","Integrative.wt.pca" ,"LectureType.wt.pca", "Repetitive.wt.pca" )
strategy.name <- c("Coop", "Deduc", "Demon", "Induc","Integ" ,"Lect", "Repet" )
teachingstrategy <- Anxiety.Analytic.Data[, stratgy.var]
names(teachingstrategy) <- strategy.name
SEM.data <- cbind(Anxiety.mea, Anxiety.mla, factor.var,teachingstrategy )
### SEM models
SEMModel <-
' Eval.Anxiety =~ MEA2 + MEA4 + MEA5 + MEA8 ## measurement model for Eval.Anxiety
Learn.Anxiety =~ MLA1 + MLA3 + MLA6 + MLA7 + MLA9 ## measurement model for Learn.Anxiety
TeacherCtrd =~ Deduc + Lect + Demon + Repet # Teacher centered
StudentCtrd =~ Coop + Induc + Integ # Student centered
Eval.Anxiety ~ Tech + Efficacy + Engage + gender + TeacherCtrd + StudentCtrd + Resource ## Eval.Anxiety as an outcome
Learn.Anxiety ~ Tech + Efficacy + Engage + gender + TeacherCtrd+ StudentCtrd + Resource ## Learn.Anxiety as an outcome
Eval.Anxiety ~~ Learn.Anxiety ## correlation between Eval.Anxiety and Learn.Anxiety
'
output <- sem(model = SEMModel, data = SEM.data, std.lv = TRUE,
missing = "fiml", mimic = "Mplus")
results <- summary(output, standardized = TRUE, fit.measures = TRUE)
The component regression ans latent models in the SEM are specified
in the following.
## measurement model for Eval.Anxiety
Eval.Anxiety =~ MEA2 + MEA4 + MEA5 + MEA8
## measurement model for Learn.Anxiety
Learn.Anxiety =~ MLA1 + MLA3 + MLA6 + MLA7 + MLA9
# Latent regression of teaching Strategies
TeacherCtrd =~ Deduc + Lect + Demon + Repet # Teacher centered
StudentCtrd =~ Coop + Induc + Integ # Student centered
## Eval.Anxiety as an outcome
Eval.Anxiety ~ Tech + Efficacy + Engage + gender + Teacher.ctrd + Student.ctrd + Resource + race
## Learn.Anxiety as an outcome
Learn.Anxiety ~ Tech + Efficacy + Engage + gender + Teacher.ctrd + Student.ctrd + Resource + race
Eval.Anxiety ~~ Learn.Anxiety ## correlation between Eval.Anxiety and Learn.Anxiety
The key goodness-of-fit statistics and estimated parameters are
summarized in the following.
interpret_fit <- function(fit_obj) {
measures <- fitMeasures(fit_obj)
#cat("=== SEM MODEL FIT ASSESSMENT ===\n")
cat(sprintf("Chi-Square: χ²(%d) = %.2f, p = %.3f\n",
measures["df"], measures["chisq"], measures["pvalue"]))
cat(sprintf("CFI: %.3f %s\n", measures["cfi"],
ifelse(measures["cfi"] >= 0.95, "(Excellent)",
ifelse(measures["cfi"] >= 0.90, "(Acceptable)", "(Poor)"))))
cat(sprintf("TLI: %.3f %s\n", measures["tli"],
ifelse(measures["tli"] >= 0.95, "(Excellent)",
ifelse(measures["tli"] >= 0.90, "(Acceptable)", "(Poor)"))))
cat(sprintf("RMSEA: %.3f [90%% CI: %.3f, %.3f] %s\n",
measures["rmsea"], measures["rmsea.ci.lower"], measures["rmsea.ci.upper"],
ifelse(measures["rmsea"] <= 0.06, "(Excellent)",
ifelse(measures["rmsea"] <= 0.08, "(Acceptable)", "(Poor)"))))
cat(sprintf("SRMR: %.3f %s\n", measures["srmr"],
ifelse(measures["srmr"] <= 0.08, "(Excellent)",
ifelse(measures["srmr"] <= 0.10, "(Acceptable)", "(Poor)"))))
}
###
report_sem <- function(fit, model_name = "The SEM") {
# Fit measures
fit_meas <- fitMeasures(fit, c("chisq", "df", "pvalue", "cfi", "tli",
"rmsea", "rmsea.ci.lower", "rmsea.ci.upper", "srmr"))
# Parameters
params <- parameterEstimates(fit)
std_params <- standardizedSolution(fit)
cat("=== STRUCTURAL EQUATION MODELING RESULTS ===\n\n")
cat("MODEL FIT:\n")
# Use the function
interpret_fit(output)
cat("\n\n")
# Significant structural paths
sig_paths <- std_params[std_params$op == "~" & std_params$pvalue < 0.1, ]
if (nrow(sig_paths) > 0) {
cat("SIGNIFICANT STRUCTURAL PATHS:\n")
for (i in 1:nrow(sig_paths)) {
cat(sprintf("- %s → %s: β = %.2f, p = %.3f\n",
sig_paths$rhs[i], sig_paths$lhs[i],
sig_paths$est[i], sig_paths$pvalue[i]))
}
cat("\n")
}
# factor loading for latent variables
cat("\n\nFACTOR LOADINGS\n\n")
print(std_params[std_params$op == "=~", ])
#####
# R-squared
r2 <- inspect(fit, "r2")
if (length(r2) > 0) {
cat("VARIANCE EXPLAINED (R²):\n\n")
for (i in 1:length(r2)) {
cat(sprintf("- %s: %.1f%%\n", names(r2)[i], r2[i] * 100))
}
}
## Regression coefficients
cat("\n\nCOEFFICIENTS OF REGRESSION\n\n")
print(std_params[std_params$op == "~", ])
# Covariance between Math Anxieties
#param_est <- parameterEstimates(fit)
cov_latent <- std_params[
std_params$lhs == "MathEval" &
std_params$rhs == "LearnAnx" &
std_params$op == "~~",
]
###
cat("\n\nCOVARIANCE :\n")
latent_cov_matrix <- lavInspect(fit, "est")$psi
cov_out <- latent_cov_matrix["Learn.Anxiety", "Eval.Anxiety"]
cat("- Learn.Anxiety and Eval.Anxiety:", cov_out)
}
# Use the function
report_sem(output, "Math Anxiety")
=== STRUCTURAL EQUATION MODELING RESULTS ===
MODEL FIT:
Chi-Square: χ²(168) = 664.84, p = 0.000
CFI: 0.928 (Acceptable)
TLI: 0.914 (Acceptable)
RMSEA: 0.065 [90% CI: 0.060, 0.070] (Acceptable)
SRMR: 0.069 (Excellent)
SIGNIFICANT STRUCTURAL PATHS:
- Tech → Eval.Anxiety: β = -0.13, p = 0.000
- Efficacy → Eval.Anxiety: β = -0.47, p = 0.000
- gender → Eval.Anxiety: β = -0.13, p = 0.000
- Tech → Learn.Anxiety: β = -0.20, p = 0.000
- Efficacy → Learn.Anxiety: β = -0.42, p = 0.000
- StudentCtrd → Learn.Anxiety: β = -0.53, p = 0.046
- Resource → Learn.Anxiety: β = 0.12, p = 0.001
FACTOR LOADINGS
lhs op rhs est.std se z pvalue ci.lower ci.upper
1 Eval.Anxiety =~ MEA2 0.886 0.012 71.001 0 0.862 0.911
2 Eval.Anxiety =~ MEA4 0.861 0.013 64.518 0 0.835 0.887
3 Eval.Anxiety =~ MEA5 0.600 0.026 22.901 0 0.549 0.651
4 Eval.Anxiety =~ MEA8 0.640 0.024 26.316 0 0.592 0.688
5 Learn.Anxiety =~ MLA1 0.510 0.031 16.607 0 0.450 0.570
6 Learn.Anxiety =~ MLA3 0.716 0.022 31.975 0 0.672 0.760
7 Learn.Anxiety =~ MLA6 0.701 0.023 30.238 0 0.656 0.747
8 Learn.Anxiety =~ MLA7 0.644 0.026 25.173 0 0.594 0.694
9 Learn.Anxiety =~ MLA9 0.723 0.022 32.396 0 0.680 0.767
10 TeacherCtrd =~ Deduc 0.887 0.010 93.255 0 0.869 0.906
11 TeacherCtrd =~ Lect 0.866 0.011 79.059 0 0.845 0.888
12 TeacherCtrd =~ Demon 0.806 0.015 55.122 0 0.778 0.835
13 TeacherCtrd =~ Repet 0.760 0.017 44.077 0 0.726 0.793
14 StudentCtrd =~ Coop 0.735 0.018 39.927 0 0.699 0.771
15 StudentCtrd =~ Induc 0.861 0.012 73.779 0 0.838 0.884
16 StudentCtrd =~ Integ 0.673 0.022 30.501 0 0.630 0.717
VARIANCE EXPLAINED (R²):
- MEA2: 78.5%
- MEA4: 74.2%
- MEA5: 36.0%
- MEA8: 41.0%
- MLA1: 26.0%
- MLA3: 51.3%
- MLA6: 49.2%
- MLA7: 41.5%
- MLA9: 52.3%
- Deduc: 78.7%
- Lect: 75.0%
- Demon: 65.0%
- Repet: 57.7%
- Coop: 54.0%
- Induc: 74.2%
- Integ: 45.4%
- Eval.Anxiety: 34.5%
- Learn.Anxiety: 33.0%
COEFFICIENTS OF REGRESSION
lhs op rhs est.std se z pvalue ci.lower ci.upper
17 Eval.Anxiety ~ Tech -0.129 0.036 -3.615 0.000 -0.198 -0.059
18 Eval.Anxiety ~ Efficacy -0.471 0.032 -14.687 0.000 -0.534 -0.408
19 Eval.Anxiety ~ Engage -0.006 0.036 -0.166 0.868 -0.077 0.065
20 Eval.Anxiety ~ gender -0.130 0.035 -3.717 0.000 -0.199 -0.061
21 Eval.Anxiety ~ TeacherCtrd -0.115 0.225 -0.512 0.609 -0.555 0.325
22 Eval.Anxiety ~ StudentCtrd -0.066 0.222 -0.298 0.766 -0.501 0.369
23 Eval.Anxiety ~ Resource -0.003 0.035 -0.084 0.933 -0.072 0.066
24 Learn.Anxiety ~ Tech -0.202 0.038 -5.375 0.000 -0.276 -0.128
25 Learn.Anxiety ~ Efficacy -0.416 0.036 -11.646 0.000 -0.486 -0.346
26 Learn.Anxiety ~ Engage -0.047 0.039 -1.217 0.224 -0.123 0.029
27 Learn.Anxiety ~ gender 0.027 0.038 0.728 0.467 -0.046 0.101
28 Learn.Anxiety ~ TeacherCtrd 0.288 0.267 1.078 0.281 -0.236 0.813
29 Learn.Anxiety ~ StudentCtrd -0.529 0.265 -1.994 0.046 -1.050 -0.009
30 Learn.Anxiety ~ Resource 0.124 0.037 3.325 0.001 0.051 0.197
COVARIANCE :
- Learn.Anxiety and Eval.Anxiety: 0.5288637
The regression coefficients and factor loadings in the above table
are summarized in the following SEM path diagram generated using
lavaanPlot function.
lavaanPlot(model = output,
coefs = TRUE,
stand = TRUE,
stars = c("regress")) # Add significance stars
The path diagram generated by R for the SEM analysis is not easy to
read. Therefore, we sketched a new path diagram that includes only the
significant regression coefficients and factor loadings.
include_graphics("FittedlSEM.png")

Results and
Discussion of SEM Anlysis
Results
The hypothesized structural equation model demonstrated an acceptable
fit to the data: \(\chi^2(168) = 664.75, p
< .001\); \(CFI = 0.927; TLI =
0.913\); \(RMSEA = 0.065 (90% CI
[0.060, 0.070])\); and \(SRMR =
0.070\) These fit indices indicate that the proposed model
adequately represents the observed data, with values meeting or
exceeding conventional thresholds for acceptable model fit.
Several significant structural paths emerged.
Technology use was a significant negative predictor of
both evaluation anxiety (\(\beta = –0.13, p
< .001\)) and learning anxiety (\(\beta = –0.20, p < .001\)), suggesting
that greater technological proficiency or integration was associated
with reduced anxiety in both contexts. Similarly, self-efficacy
negatively predicted evaluation anxiety (\(\beta = –0.47, p < .001\)) and learning
anxiety (\(\beta = –0.42, p <
.001\)), indicating that individuals with higher self-efficacy
experienced lower levels of anxiety.
Gender also had a significant effect on evaluation
anxiety (\(\beta = –0.13, p <
.001\)), implying potential gender-based differences in
evaluation-related apprehension. Although student-centered
instruction was marginally related to learning anxiety (\(\beta = –0.51, p = .059\)),
resource availability positively predicted learning
anxiety (\(\beta = 0.12, p = .001\)),
indicating that access to additional resources may not uniformly
alleviate anxiety and could, in some contexts, contribute to
increased pressure or cognitive load. Other
hypothesized paths (e.g., engagement,
teacher-centered approaches) were not statistically
significant (all \(p > .05\)).
All observed indicators loaded significantly onto their respective
latent constructs (all \(p <
.001\)), with standardized factor loadings ranging from 0.51 to
0.88, supporting construct validity. For Evaluation Anxiety, the
strongest indicators were MEA2 (\(\lambda = 0.883\)) and
MEA4 (\(\lambda =
0.857\)). For Learning Anxiety, the highest loadings were
observed for MLA9 (\(\lambda
= 0.725\)) and MLA3 (\(\lambda = 0.714\)). Among teaching
approaches, Teacher-Centered Instruction was best
represented by Deductive (\(\lambda = 0.886\)) and
Lecture (\(\lambda =
0.868\)) methods, while Student-Centered
Instruction was best reflected by Inductive
(\(\lambda = 0.862\)) and
Cooperative (\(\lambda =
0.733\)) strategies.
The model accounted for 34.9% of the variance in evaluation anxiety
and 33.4% of the variance in learning anxiety, indicating moderate
explanatory power. The covariance between evaluation anxiety and
learning anxiety was significant and positive (\(r = 0.53\)), suggesting that while
distinct, these two forms of anxiety are moderately correlated.
Overall, the results highlight the pivotal role of
self-efficacy and technology use in
mitigating both evaluation and learning-related anxiety. These findings
align with prior research emphasizing that confidence in one’s abilities
and familiarity with digital tools can enhance perceived control and
reduce anxiety in academic contexts. The marginal influence of
student-centered approaches suggests potential benefits
for reducing learning anxiety through active and participatory learning
environments, although the effect did not reach conventional
significance. The positive association between resource
availability and anxiety may indicate that while access to
materials supports learning, it can also introduce information overload
or performance expectations that heighten anxiety. Together, these
findings underscore the multifaceted nature of academic anxiety and
point to the importance of fostering efficacy and technological
readiness to create supportive learning environments.
These findings collectively inform the subsequent discussion on how
instructional design, self-efficacy,
and technology integration interact to influence
learners’ emotional experiences and academic engagement.
Discussion
The present study investigated the structural relationships among
technology use, self-efficacy, instructional approaches, and two forms
of academic anxiety—evaluation anxiety and learning anxiety—within a
comprehensive structural equation modeling (SEM) framework. The findings
provide important insights into how individual and instructional factors
jointly shape learners’ emotional experiences in academic contexts.
Consistent with prior research, self-efficacy emerged as the most
robust predictor of both evaluation and learning anxiety. Students who
reported higher confidence in their academic abilities experienced
significantly lower levels of anxiety, underscoring the protective
function of self-belief in coping with academic demands. Similarly,
technology use negatively predicted both types of anxiety, suggesting
that familiarity and comfort with technological tools may help students
navigate learning environments more effectively and reduce apprehension
about performance.
Although student-centered instruction was only marginally associated
with reduced learning anxiety, the direction of this relationship is
theoretically meaningful. Learners exposed to inductive, cooperative,
and integrative teaching strategies may perceive greater autonomy and
support, which can lessen anxiety and foster intrinsic motivation. The
positive association between resource availability and learning anxiety
suggests that access to abundant materials does not necessarily
alleviate stress; instead, it may introduce cognitive overload or
performance pressure.
Gender significantly predicted evaluation anxiety, highlighting the
importance of considering sociocultural and disciplinary factors that
shape how gender interacts with academic emotions. The strong positive
covariance between evaluation and learning anxiety indicates that these
constructs are related yet distinct, supporting theories that emphasize
interconnected emotional experiences in learning.
The findings underscore the need for instructional designs that
enhance self-efficacy and technological confidence as central strategies
for reducing academic anxiety. Instructors can promote self-efficacy
through scaffolded feedback, mastery-oriented assessments, and
opportunities for self-reflection. Purposeful technology integration and
structured guidance can further support confidence and reduce anxiety.
Future studies should explore additional predictors and contextual
variables, as well as employ longitudinal designs to clarify causal
pathways.
In summary, the findings demonstrate that self-efficacy and
technology use are key protective factors against both evaluation and
learning anxiety, whereas instructional context and resource management
play secondary roles. These insights contribute to a growing
understanding of how personal and pedagogical factors interact to shape
emotional experiences in learning environments.
Practical
Implications
- Enhance Students’ Self-Efficacy: Provide opportunities for early
success, mastery experiences, and positive feedback to build learners’
confidence.
- Promote Meaningful Technology Integration: Integrate digital tools
purposefully within instruction to foster engagement and reduce
technology-related anxiety.
- Adopt Student-Centered Teaching Practices: Encourage collaborative,
problem-based, and peer-driven learning to alleviate anxiety and promote
autonomy.
- Balance Resource Provision and Cognitive Load: Curate instructional
materials carefully to prevent information overload and ensure clarity
of expectations.
- Address Gender and Contextual Differences: Tailor support strategies
to address potential gender-based and contextual variations in academic
anxiety.
Summary of Key
Findings
This study employed structural equation modeling to examine the
interplay among technology use, self-efficacy, instructional approaches,
and two dimensions of academic anxiety: evaluation anxiety and learning
anxiety. The model demonstrated an acceptable overall fit and explained
a substantial proportion of variance in both outcomes.
The results revealed that self-efficacy and technology use were the
strongest protective factors against academic anxiety. Self-efficacy had
the largest negative associations with both evaluation and learning
anxiety, indicating that students who feel competent are less likely to
experience anxiety across academic contexts. Technology use similarly
reduced anxiety, suggesting that familiarity with digital tools fosters
comfort and perceived control during learning and assessment.
While student-centered instruction showed a marginally negative
relationship with learning anxiety, resource availability unexpectedly
predicted higher anxiety. Gender differences also emerged for evaluation
anxiety, suggesting variation in emotional responses to academic
evaluation across groups.
Together, these findings demonstrate that fostering self-efficacy,
digital competence, and balanced instructional design can substantially
reduce students’ anxiety and promote more positive academic experiences.
The study contributes to a growing body of evidence highlighting the
interconnected roles of personal beliefs, technology, and pedagogy in
shaping students’ emotional engagement and success.
References
Borich, G. D. (2017). Effective Teaching Methods: Research-Based
Practice (9th ed.). Pearson. Brown, H. D., & Lee, H. (1994).
Teaching by principles: An interactive approach to language pedagogy
(Vol. 1, p. 994). Englewood Cliffs, NJ: Prentice Hall Regents.
Bruner, J. S. (1961). The act of discovery. Harvard educational
review. Cattell, R. B. (1952). Factor analysis: an introduction and
manual for the psychologist and social scientist.
Chang, H., & Beilock, S. L. (2016). The math anxiety-math
performance link and its relation to individual and environmental
factors: A review of current behavioral and psychophysiological
research. Current Opinion in Behavioral Sciences, 10, 33–38.
Cronbach, L. J. (1951). Coefficient alpha and the internal structure
of tests. Biometrika, 16, 297–335.
Daker, R. J., Gattas, S. U., Sokolowski, H. M., Green, A. E., &
Lyons, I. M. (2021). First-year students’ math anxiety predicts STEM
avoidance and underperformance throughout university, independently of
math ability. Npj Science of Learning, 6(1), 17.
Devine, A., Fawcett, K., Szűcs, D., & Dowker, A. (2012). Gender
differences in mathematics anxiety and the relation to mathematics
performance while controlling for test anxiety. Behavioral and brain
functions, 8(1), 33.
DiStefano, C., Zhu, M., & Mindrila, D. (2009). Understanding and
using factor scores: Considerations for the applied researcher.
Practical assessment, research, and evaluation, 14(1).
Dreger, R. M., & Aiken Jr, L. R. (1957). The identification of
number anxiety in a college population. Journal of Educational
Psychology, 48(6), 344.
Duncan, O. D. (1961). A socioeconomic index for all occupations.
Occupations and social status..
Else-Quest, N. M., Hyde, J. S., & Linn, M. C. (2010).
Cross-national patterns of gender differences in mathematics: a
meta-analysis. Psychological bulletin, 136(1), 103.
Fogarty, R. (1991). The mindful school: How to integrate the
curricula. Palatine, IL. SkyLight Publishing, Inc. Retrieved February,
22, 2002.
Goetz, T., Bieg, M., Lüdtke, O., Pekrun, R., & Hall, N. C.
(2013). Do girls really experience more anxiety in mathematics?.
Psychological science, 24(10), 2079-2087.
Gough, Mary O. (1954). Why failures in mathematics? Mathemaphobia:
Causes and treatments. The Clearing House: A Journal of Educational
Strategies, Issues and Ideas, 28(5), 290–294.
Guttman, L. (1954). Some necessary conditions for common-factor
analysis. Psychometrika, 19(2), 149-161.
Hembree, R. (1990). The nature, effects, and relief of mathematics
anxiety. Journal for research in mathematics education, 21(1),
33-46.
Hopko, D. R., Mahadevan, R., Bare, R. L., & Hunt, M. K. (2003).
The abbreviated math anxiety scale (AMAS) construction, validity, and
reliability. Assessment, 10(2), 178–182.
Hirschberg, E., & Standish, C. V. (1959). A method of deriving a
stratification score by using the principal components of the
correlation matrix. American Statistical Association, Proceedings of the
Social Statistics Section, 1959, 220-225.
Jacobs, H. H. (1989). Interdisciplinary curriculum: Design and
implementation. Association for Supervision and Curriculum Development,
1250 N. Pitt Street, Alexandria, VA 22314.
Jolliffe, I. T., & Cadima, J. (2016). Principal Component
Analysis: A Review and Recent Developments. Philosophical Transactions
of the Royal Society A, 374(2065), 20150202.
Johnson, D. W., Johnson, R. T., & Smith, K. A. (2014).
Cooperative learning: Improving university instruction by basing
practice on validated theory. Journal on excellence in college teaching,
25(3&4).
Jose M. Cardino Jr. and Ruth A. Ortega-Dela Cruz, Understanding of
learning styles and teaching strategies towards improving the teaching
and learning of mathematics, LUMAT General Issue, Vol 8 No 1 (2020),
19–43. Doi: 10.31129/ LUMAT.8.1.1348
Joyce, B., Weil, M., & Calhoun, E. (2015). Models of Teaching
(9th ed.). Pearson.
Klee, H. L., Buehl, M. M., & Miller, A. D. (2022). Strategies for
alleviating students’ math anxiety: Control-value theory in practice.
Theory Into Practice, 61(1), 49–61.
Lazarsfeld, P. F., Stouffer, S. A., Guttman, L., & Suchman, E. A.
(1950). Measurement and prediction. SA Stouffer (éd.) Studies in social
psychology in world war II, 4.
López-Bonilla, J. M.l and López-Bonilla, L. M. (2012), Validation of
an information technology anxiety scale in undergraduates, British
Journal of Educational Technology Vol 43. No 2. E56–E58. doi:10.1111/j.1467-8535.2011.01256.x
Marsh, H. W. (1996). Positive and negative self-esteem: A
substantively meaningful distinction or artifactors? Journal of
Personality and Social Psychology, 70(4), 810–819.
McDonald, R. P. (1999). Test theory: A unified treatment. Mahwah:
Erlbaum.
Moliner, L., & Alegre, F. (2020). Peer tutoring effects on
students’ mathematics anxiety: A middle school experience. Frontiers in
Psychology, 11, 1610.
O’Leary, K., Fitzpatrick, C. L., & Hallett, D. (2017). Math
anxiety is related to some, but not all, experiences with math.
Frontiers in Psychology, 8, 2067.
Ormrod, J. E. (2020). Human Learning (8th ed.). Pearson
Pletzer, B., Wood, G., Scherndl, T., Kerschbaum, H. H., & Nuerk,
H.C. (2016). Components of mathematics anxiety: Factor modeling of the
MARS30-brief. Frontiers in Psychology, 7, 91.
Prince, M. J., & Felder, R. M. (2006). Inductive teaching and
learning methods: Definitions, comparisons, and research bases. Journal
of engineering education, 95(2), 123-138.
Richardson, F. C., & Suinn, R. M. (1972). The mathematics anxiety
rating scale: Psychometric data. Journal of Counseling Psychology,
19(6), 551.
Rozgonjuk, D., Kraav, T., Mikkor, K., Orav-Puurand, K., & Täht,
K. (2020). Mathematics anxiety among STEM and social science students:
The roles of mathematics self-efficacy, and deep and surface approach to
learning. International Journal of STEM Education, 7(1), 1–11.
Segool, N. K., Carlson, J. S., Goforth, A. N., Von Der Embse, N.,
& Barterian, J. A. (2013). Heightened test anxiety among young
children: Elementary school students’ anxious responses to high-stakes
testing. Psychology in the Schools, 50(5), 489–499.
Watson, D., Clark, L. A., & Tellegen, A. (1988). Development and
validation of brief measures of positive and negative affect: The PANAS
scales. Journal of Personality and Social Psychology, 54(6),
1063–1070.
Wilson, S. (2013). Mature age pre-service teachers’ mathematics
anxiety and factors impacting on university retention. Mathematics
Education: Yesterday, Today and Tomorrow (MERGA36), 666–673.
Appendices
Mathematics of
PCA
1. Problem Definition
We will use a questionnaire with four items that assess math
evaluation anxiety to demonstrate the procedure.
- \(x_1\): Thinking about a math test
the day before you take it.
- \(x_2\): Taking a math test.
- \(x_3\): Being given a homework
assignment of many difficult problems that is due for the next class
meeting.
- \(x_4\): Being given a quiz on math
without knowing in advance.
Let \(\mathbf{x} = [x_1, x_2, x_3,
x_4]^T\) be a random vector representing the responses of a
randomly selected individual to the four items. We assume \(\mathbf{x}\) has a population mean vector
\(\boldsymbol{\mu}\) and population
covariance matrix \(\boldsymbol{\Sigma}\).
We collect a sample of \(n\)
individuals. The data matrix is \(\mathbf{X}_{n \times 4}\), where each row
is an individual’s response vector. The sample mean vector is \(\bar{\mathbf{x}}\), and the sample
covariance matrix is \(\mathbf{S}\).
2. Preprocessing: Centering the Data
The first step is to center the data. We subtract the mean of each
variable, creating a new data matrix \(\mathbf{Y}\):
\[
\mathbf{Y} = \mathbf{X} - \mathbf{1}\bar{\mathbf{x}}^T
\]
where \(\mathbf{1}\) is an \(n \times 1\) vector of ones. The elements
of \(\mathbf{Y}\) are \(y_{ij} = x_{ij} - \bar{x}_j\). From this
point forward, we work with the centered data \(\mathbf{Y}\), ensuring \(E[\mathbf{y}] = \mathbf{0}\).
3. Goal of Principal Component Analysis (PCA)
The goal of PCA is to find a new set of uncorrelated variables \(\mathbf{z} = [z_1, z_2, z_3, z_4]^T\),
called the (PCs), which are linear combinations of the original centered
variables \(\mathbf{y}\).
\[
\mathbf{z} = \mathbf{W}^T\mathbf{y}
\]
The matrix \(\mathbf{W}\) is an
orthogonal matrix (\(\mathbf{W}^T\mathbf{W} =
\mathbf{I}\)) whose columns \(\mathbf{w}_i\) are the . The components
must satisfy:
- The first component, \(z_1 =
\mathbf{w}_1^T \mathbf{y}\), has the maximum possible
variance.
- The \(k\)-th component, \(z_k = \mathbf{w}_k^T \mathbf{y}\), has the
maximum possible variance subject to being uncorrelated with (orthogonal
to) all previous components \(z_1, \dots,
z_{k-1}\).
4. Derivation of the First Principal Component
Let \(\mathbf{w}_1\) be the vector
of weights for the first PC, \(z_1 =
\mathbf{w}_1^T \mathbf{y}\). The sample variance of \(z_1\) is given by:
\[
\begin{align*}
\text{Var}(z_1) &= \text{Var}(\mathbf{w}_1^T \mathbf{y}) \\
&= E[(\mathbf{w}_1^T \mathbf{y})(\mathbf{w}_1^T
\mathbf{y})^T] \quad \text{(since} E[\mathbf{y}]=\mathbf{0}) \\
&= E[\mathbf{w}_1^T \mathbf{y} \mathbf{y}^T
\mathbf{w}_1] \\
&= \mathbf{w}_1^T E[\mathbf{y} \mathbf{y}^T]
\mathbf{w}_1 \\
&= \mathbf{w}_1^T \boldsymbol{\Sigma} \mathbf{w}_1
\end{align*}
\]
In practice, we use the sample covariance matrix \(\mathbf{S} = \frac{1}{n-1} \mathbf{Y}^T
\mathbf{Y}\).
We wish to maximize \(\mathbf{w}_1^T
\mathbf{S} \mathbf{w}_1\) subject to the normalization constraint
\(\mathbf{w}_1^T \mathbf{w}_1 = 1\) (to
prevent the variance from growing arbitrarily large). We solve this
using the method of Lagrange multipliers.
The Lagrangian is:
\[
\mathcal{L}(\mathbf{w}_1, \lambda_1) = \mathbf{w}_1^T \mathbf{S}
\mathbf{w}_1 - \lambda_1 (\mathbf{w}_1^T \mathbf{w}_1 - 1)
\]
Taking the gradient with respect to \(\mathbf{w}_1\) and setting it to zero:
\[
\frac{\partial \mathcal{L}}{\partial \mathbf{w}_1} =
2\mathbf{S}\mathbf{w}_1 - 2\lambda_1 \mathbf{w}_1 = 0
\]
This yields the key :
\[
\begin{equation}
\mathbf{S} \mathbf{w}_1 = \lambda_1 \mathbf{w}_1
\end{equation}
\]
Substituting the above equation back into the variance
expression:
\[
\text{Var}(z_1) = \mathbf{w}_1^T \mathbf{S} \mathbf{w}_1 =
\mathbf{w}_1^T (\lambda_1 \mathbf{w}_1) = \lambda_1 \mathbf{w}_1^T
\mathbf{w}_1 = \lambda_1
\]
Thus, the variance of the first principal component \(z_1\) is the eigenvalue \(\lambda_1\). To maximize the variance, we
must choose the .
5. Derivation of the Second Principal Component
We now seek the second component \(z_2 =
\mathbf{w}_2^T \mathbf{y}\) that has maximum variance, subject to
\(\mathbf{w}_2^T \mathbf{w}_2 = 1\) and
\(\mathbf{w}_2^T \mathbf{w}_1 = 0\)
(ensuring \(z_2\) is uncorrelated with
\(z_1\)).
The Lagrangian for this problem is:
\[
\mathcal{L}(\mathbf{w}_2, \lambda_2, \phi) = \mathbf{w}_2^T \mathbf{S}
\mathbf{w}_2 - \lambda_2 (\mathbf{w}_2^T \mathbf{w}_2 - 1) - \phi
(\mathbf{w}_2^T \mathbf{w}_1)
\]
Taking the gradient with respect to \(\mathbf{w}_2\) and setting it to zero:
\[
\frac{\partial \mathcal{L}}{\partial \mathbf{w}_2} =
2\mathbf{S}\mathbf{w}_2 - 2\lambda_2 \mathbf{w}_2 - \phi \mathbf{w}_1 =
0
\]
Multiply this equation on the left by \(\mathbf{w}_1^T\):
\[
2\mathbf{w}_1^T\mathbf{S}\mathbf{w}_2 - 2\lambda_2
\mathbf{w}_1^T\mathbf{w}_2 - \phi \mathbf{w}_1^T\mathbf{w}_1 = 0
\]
From the eigenvalue equation for \(\mathbf{w}_1\), we know \(\mathbf{w}_1^T\mathbf{S} = \lambda_1
\mathbf{w}_1^T\). The orthogonality constraint gives \(\mathbf{w}_1^T\mathbf{w}_2=0\).
Substituting these:
\[
2\lambda_1 \mathbf{w}_1^T\mathbf{w}_2 - 0 - \phi (1) = 0 \implies
2\lambda_1 (0) - \phi = 0 \implies \phi = 0
\]
With \(\phi=0\), the gradient
equation simplifies to:
\[
2\mathbf{S}\mathbf{w}_2 - 2\lambda_2 \mathbf{w}_2 = 0 \implies
\mathbf{S} \mathbf{w}_2 = \lambda_2 \mathbf{w}_2
\]
This is again an eigenvalue equation. The variance of \(z_2\) is \(\lambda_2\). To maximize the variance, we
choose the eigenvector \(\mathbf{w}_2\)
corresponding to the \(\lambda_2\). The
orthogonality \(\mathbf{w}_2^T \mathbf{w}_1 =
0\) is automatically satisfied for distinct eigenvalues since
\(\mathbf{S}\) is symmetric.
6. Subsequent Components and Full Solution
This process continues for all four components. The solution to the
PCA problem is found by performing the of the sample covariance matrix
\(\mathbf{S}\):
\[
\mathbf{S} = \mathbf{W} \boldsymbol{\Lambda} \mathbf{W}^T
\]
where:
- \(\boldsymbol{\Lambda}\) is a
diagonal matrix containing the eigenvalues in descending order: \(\lambda_1 \ge \lambda_2 \ge \lambda_3 \ge
\lambda_4 \ge 0\).
- \(\mathbf{W} = [\mathbf{w}_1,
\mathbf{w}_2, \mathbf{w}_3, \mathbf{w}_4]\) is an orthogonal
matrix whose columns are the corresponding eigenvectors.
The principal components for an individual with centered response
vector \(\mathbf{y}\) are then computed
as:
\[
\mathbf{z} = \mathbf{W}^T \mathbf{y}
\]
The \(k\)-th PC score is \(z_k = \mathbf{w}_k^T \mathbf{y}\).
7. Variance Explained
The total variance in the original data is the sum of the variances
of the centered variables, which is the trace of \(\mathbf{S}\).
\[
\text{Total Variance} = \text{tr}(\mathbf{S}) = s_{11}^2 + s_{22}^2 +
s_{33}^2 + s_{44}^2
\]
For a symmetric matrix, this is also equal to the sum of its
eigenvalues:
\[
\text{Total Variance} = \lambda_1 + \lambda_2 + \lambda_3 + \lambda_4
\] The proportion of total variance explained by the \(k\)-th principal component is:
\[
\text{Proportion}_k = \frac{\lambda_k}{\sum_{i=1}^{4} \lambda_i}
\]
The cumulative variance explained by the first \(m\) components is:
\[
\text{Cumulative}_m = \frac{\sum_{i=1}^{m} \lambda_i}{\sum_{i=1}^{4}
\lambda_i}
\]
8. Interpretation in our Context
In the context of our math evaluation anxiety questionnaire:
The loading vector \(\mathbf{w}_1 =
[w_{11}, w_{12}, w_{13}, w_{14}]^T\) reveals how the original
items combine to form the primary latent dimension of anxiety. For
example, if all loadings are positive and similar, \(z_1\) might represent .
The second component \(\mathbf{w}_2\) might contrast different
types of anxiety. For instance, if \(w_{21}\) and \(w_{22}\) (test-related) are positive while
\(w_{23}\) and \(w_{24}\) (pop quiz/homework) are negative,
\(z_2\) might represent .
By examining the loadings, we can interpret the underlying
psychological constructs that drive the correlations between the four
questionnaire items.
Confirmatice Factor
Analysis (CFA)
This appendix provides a detailed mathematical derivation of a
Confirmatory Factor Analysis (CFA) model. The observed variables are
nine items related to mathematical anxiety, which are hypothesized to
load onto two latent factors: and .
1. Latent Factors and Observed Variables
We define two latent factors:
- \(\eta_1\): Test Anxiety (TA)
- \(\eta_2\): Learning Anxiety
(LA)
We have nine observed variables (items/questions), \(y_1\) to \(y_9\):
- \(y_1\): Having to use tables in
the back of a math book.
- \(y_2\): Thinking about a math test
the day before you take it.
- \(y_3\): Watching the teacher work
out a math problem on the board.
- \(y_4\): Taking a math test.
- \(y_5\): Being given a homework
assignment of many difficult problems that is due for the next class
meeting.
- \(y_6\): Listening to a lecture in
math class.
- \(y_7\): Listening to another
student explain how to do a math problem.
- \(y_8\): Being given a quiz on math
without knowing in advance.
- \(y_9\): Starting a new chapter in
a math book.
2. Factor Loadings and Model Structure
We hypothesize the following factor structure:
- Factor \(\eta_1\) (Test Anxiety)
loads on items \(y_2\), \(y_4\), \(y_5\), and \(y_8\).
- Factor \(\eta_2\) (Learning
Anxiety) loads on items \(y_1\), \(y_3\), \(y_6\), \(y_7\), and \(y_9\).
The fundamental equation for a CFA model for a single observed
variable \(y_i\) is:
\[
y_i = \nu_i + \lambda_{i1} \eta_1 + \lambda_{i2} \eta_2 + \epsilon_i
\]
where:
- \(\nu_i\) is the intercept for
observed variable \(y_i\).
- \(\lambda_{i1}\) is the factor
loading of \(y_i\) on latent factor
\(\eta_1\).
- \(\lambda_{i2}\) is the factor
loading of \(y_i\) on latent factor
\(\eta_2\).
- \(\epsilon_i\) is the unique factor
(measurement error) for \(y_i\).
3. The Measurement Model in Matrix Form
The model for all nine observed variables can be written compactly in
matrix form. We define the following vectors and matrices:
- \(\mathbf{y} = (y_1, y_2, \dots,
y_9)^T\) is a \(9 \times 1\)
vector of observed variables.
- \(\boldsymbol{\nu} = (\nu_1, \nu_2, \dots,
\nu_9)^T\) is a \(9 \times 1\)
vector of intercepts.
- \(\boldsymbol{\eta} = (\eta_1,
\eta_2)^T\) is a \(2 \times 1\)
vector of latent factors.
- \(\boldsymbol{\Lambda}\) is a \(9 \times 2\) matrix of factor loadings
\(\lambda_{ij}\).
- \(\boldsymbol{\epsilon} = (\epsilon_1,
\epsilon_2, \dots, \epsilon_9)^T\) is a \(9 \times 1\) vector of measurement
errors.
The full measurement model is:
\[
\mathbf{y} = \boldsymbol{\nu} + \boldsymbol{\Lambda} \boldsymbol{\eta} +
\boldsymbol{\epsilon}
\]
Given our hypothesized factor structure, the loading matrix \(\boldsymbol{\Lambda}\) has a specific form
with many elements fixed to zero. To ensure model identification, we
need to set the scale of each latent variable. This is typically done by
, where the variance of the latent factor is fixed to 1, or by method,
where one loading per factor is fixed to 1. We will use the latter.
Let us define:
- \(y_2\) as the marker variable for
\(\eta_1\) (Test Anxiety), so \(\lambda_{21} = 1\).
- \(y_1\) as the marker variable for
\(\eta_2\) (Learning Anxiety), so \(\lambda_{12} = 1\).
The \(\boldsymbol{\Lambda}\) matrix
is then:
\[
\boldsymbol{\Lambda} =
\begin{bmatrix}
0 & 1 \\ % y1 loads on eta2 (LA)
1 & 0 \\ % y2 loads on eta1 (TA)
0 & \lambda_{32} \\ % y3 loads on eta2 (LA)
\lambda_{41} & 0 \\ % y4 loads on eta1 (TA)
\lambda_{51} & 0 \\ % y5 loads on eta1 (TA)
0 & \lambda_{62} \\ % y6 loads on eta2 (LA)
0 & \lambda_{72} \\ % y7 loads on eta2 (LA)
\lambda_{81} & 0 \\ % y8 loads on eta1 (TA)
0 & \lambda_{92} \\ % y9 loads on eta2 (LA)
\end{bmatrix}
\]
4. Model Assumptions
The CFA model relies on several key assumptions:
The errors have a mean of zero: \(E(\boldsymbol{\epsilon}) =
\mathbf{0}\).
The errors are uncorrelated with the factors: \(\mathrm{Cov}(\boldsymbol{\eta},
\boldsymbol{\epsilon}) = \mathbf{0}\).
The errors may be correlated with each other, but in a basic
model, we often assume they are uncorrelated: \(\boldsymbol{\Theta}_{\epsilon} =
\mathrm{Cov}(\boldsymbol{\epsilon}) = \mathrm{diag}(\theta_{11},
\theta_{22}, \dots, \theta_{99})\), where \(\theta_{ii} =
\mathrm{Var}(\epsilon_i)\).
5. Derivation of the Implied Covariance Matrix
The core of CFA is to model the population covariance matrix of the
observed variables, \(\boldsymbol{\Sigma}\). The model-implied
covariance matrix, denoted \(\boldsymbol{\Sigma}(\boldsymbol{\theta})\),
is a function of the model parameters \(\boldsymbol{\theta}\) (loadings, factor
variances/covariances, error variances).
Let \(\boldsymbol{\Psi}\) be the
\(2 \times 2\) covariance matrix of the
latent factors:
\[
\boldsymbol{\Psi} = \mathrm{Cov}(\boldsymbol{\eta}) =
\begin{bmatrix}
\psi_{11} & \psi_{12} \\
\psi_{21} & \psi_{22}
\end{bmatrix}
=
\begin{bmatrix}
\mathrm{Var}(\eta_1) & \mathrm{Cov}(\eta_1, \eta_2) \\
\mathrm{Cov}(\eta_1, \eta_2) & \mathrm{Var}(\eta_2)
\end{bmatrix}
\]
The implied covariance matrix \(\boldsymbol{\Sigma}(\boldsymbol{\theta})\)
is derived as follows:
\[
\begin{align*}
\boldsymbol{\Sigma}(\boldsymbol{\theta}) &= \mathrm{Cov}(\mathbf{y})
\\
&= \mathrm{Cov}(\boldsymbol{\nu} +
\boldsymbol{\Lambda}\boldsymbol{\eta} + \boldsymbol{\epsilon}) \\
&= \mathrm{Cov}(\boldsymbol{\Lambda}\boldsymbol{\eta} +
\boldsymbol{\epsilon}) \quad \text{(since } \boldsymbol{\nu} \text{ is a
constant)} \\
&= \mathrm{Cov}(\boldsymbol{\Lambda}\boldsymbol{\eta}) +
\mathrm{Cov}(\boldsymbol{\epsilon}) +
\mathrm{Cov}(\boldsymbol{\Lambda}\boldsymbol{\eta},
\boldsymbol{\epsilon}) + \mathrm{Cov}(\boldsymbol{\epsilon},
\boldsymbol{\Lambda}\boldsymbol{\eta})
\end{align*}
\]
Using assumption 2 (\(\mathrm{Cov}(\boldsymbol{\eta},
\boldsymbol{\epsilon}) = \mathbf{0}\)), the cross-terms
vanish:
\[
\mathrm{Cov}(\boldsymbol{\Lambda}\boldsymbol{\eta},
\boldsymbol{\epsilon}) = \boldsymbol{\Lambda}
\mathrm{Cov}(\boldsymbol{\eta}, \boldsymbol{\epsilon}) = \mathbf{0},
\quad \mathrm{Cov}(\boldsymbol{\epsilon},
\boldsymbol{\Lambda}\boldsymbol{\eta}) = \mathbf{0}
\]
Therefore,
\[
\begin{align*}
\boldsymbol{\Sigma}(\boldsymbol{\theta}) &=
\mathrm{Cov}(\boldsymbol{\Lambda}\boldsymbol{\eta}) +
\mathrm{Cov}(\boldsymbol{\epsilon}) \\
&= \boldsymbol{\Lambda} \mathrm{Cov}(\boldsymbol{\eta})
\boldsymbol{\Lambda}^T + \boldsymbol{\Theta}_{\epsilon} \\
&= \boldsymbol{\Lambda} \boldsymbol{\Psi} \boldsymbol{\Lambda}^T +
\boldsymbol{\Theta}_{\epsilon}
\end{align*}
\]
This is the fundamental equation for the implied covariance matrix in
CFA:
\[
\boxed{\boldsymbol{\Sigma}(\boldsymbol{\theta}) = \boldsymbol{\Lambda}
\boldsymbol{\Psi} \boldsymbol{\Lambda}^T +
\boldsymbol{\Theta}_{\epsilon}}
\]
6. Parameter Estimation and Model Identification
The goal of estimation is to find parameter values \(\hat{\boldsymbol{\theta}}\) such that \(\boldsymbol{\Sigma}(\hat{\boldsymbol{\theta}})\)
is as close as possible to the sample covariance matrix \(\mathbf{S}\) obtained from the data.
For identification, the number of free parameters \(t\) must be less than or equal to the
number of non-redundant elements in \(\mathbf{S}\), which is \(\frac{p(p+1)}{2}\) where \(p\) is the number of observed variables
(\(p=9\)).
Let’s count our free parameters \(t\):
Factor Loadings (\(\boldsymbol{\Lambda}\))}: We fixed \(\lambda_{21}\) and \(\lambda_{12}\) to 1. We have 7 free
loadings: \(\lambda_{32}\), \(\lambda_{41}\), \(\lambda_{51}\), \(\lambda_{62}\), \(\lambda_{72}\), \(\lambda_{81}\), \(\lambda_{92}\).
Latent Factor Covariances (\(\boldsymbol{\Psi}\))}: We have 3 free
parameters: \(\psi_{11}\) (variance of
TA), \(\psi_{22}\) (variance of LA),
and \(\psi_{12}\) (covariance between
TA and LA).
Error Variances (\(\boldsymbol{\Theta}_{\epsilon}\))}: We have
9 free parameters: \(\theta_{11}, \theta_{22},
\dots, \theta_{99}\).
Total free parameters: \(t = 7 + 3 + 9 =
19\).
The number of non-redundant elements in \(\mathbf{S}\) is \(\frac{9 \times (9+1)}{2} = 45\).
Since \(45 > 19\), the model is
with \(df = 45 - 19 = 26\) degrees of
freedom. This is a necessary condition for identification, and with the
scaling constraints we placed, the model is identified.
7. Conclusion
This derivation has outlined the complete mathematical setup for a
two-factor CFA model of mathematical anxiety. The model posits that the
covariation among the nine observed items can be explained by two
correlated latent factors. The next step would be to use an estimation
algorithm (e.g., Maximum Likelihood) to find the parameter values that
minimize the difference between \(\boldsymbol{\Sigma}(\boldsymbol{\theta})\)
and the sample covariance matrix \(\mathbf{S}\), and then assess the model’s
fit to the data.
Mathematical
Formulation of SEM Model
1. Model Specification
Let the model consist of the following components:
- Exogenous latent variables: \(\boldsymbol{\xi} = (\xi_1, \xi_2)^T\),
where:
- \(\xi_1\): Teacher-centered
- \(\xi_2\): Student-centered
- Endogenous latent variables: \(\boldsymbol{\eta} = (\eta_1, \eta_2)^T\),
where:
- \(\eta_1\): Math Evaluation Anxiety
(MEA)
- \(\eta_2\): Math Learning Anxiety
(MLA)
- Observed indicators for Teacher-centered: \(\mathbf{x}_1 = (x_1, x_2, x_3, x_4)^T\)
where:
- \(x_1\): Deductive
- \(x_2\): Lecture
- \(x_3\): Demonstration
- \(x_4\): Repetitive
- Observed indicators for Student-centered: \(\mathbf{x}_2 = (x_5, x_6, x_7)^T\) where:
- \(x_5\): Cooperative
- \(x_6\): Inductive
- \(x_7\): Integrative
- Observed indicators for MEA: \(\mathbf{y}_1 = (y_1, y_2, y_3, y_4)^T\)
(MEA1-MEA4)
- Observed indicators for MLA: \(\mathbf{y}_2 = (y_5, y_6, y_7, y_8,
y_9)^T\) (MLA1, MLA3, MLA6, MLA7, MLA9)
- Exogenous observed variables: \(\mathbf{w} = (w_1, w_2, w_3, w_4, w_5)^T\)
where:
- \(w_1\): Self-efficacy
- \(w_2\): Technology
- \(w_3\): Engagement
- \(w_4\): Gender
- \(w_5\): Resource
2. Measurement Models
For exogenous latent variables:
\[
\begin{align*}
\mathbf{x} &= \boldsymbol{\Lambda}_x \boldsymbol{\xi} +
\boldsymbol{\delta} \\
\begin{bmatrix}
x_1 \\ x_2 \\ x_3 \\ x_4 \\ x_5 \\ x_6 \\ x_7
\end{bmatrix}
&=
\begin{bmatrix}
\lambda_{1,1} & 0 \\
\lambda_{2,1} & 0 \\
\lambda_{3,1} & 0 \\
\lambda_{4,1} & 0 \\
0 & \lambda_{5,2} \\
0 & \lambda_{6,2} \\
0 & \lambda_{7,2}
\end{bmatrix}
\begin{bmatrix}
\xi_1 \\ \xi_2
\end{bmatrix}
+
\begin{bmatrix}
\delta_1 \\ \delta_2 \\ \delta_3 \\ \delta_4 \\ \delta_5 \\ \delta_6 \\
\delta_7
\end{bmatrix}
\end{align*}
\]
For endogenous latent variables:
\[
\begin{align*}
\mathbf{y} &= \boldsymbol{\Lambda}_y \boldsymbol{\eta} +
\boldsymbol{\epsilon} \\
\begin{bmatrix}
y_1 \\ y_2 \\ y_3 \\ y_4 \\ y_5 \\ y_6 \\ y_7 \\ y_8 \\ y_9
\end{bmatrix}
&=
\begin{bmatrix}
\lambda_{1,1}^y & 0 \\
\lambda_{2,1}^y & 0 \\
\lambda_{3,1}^y & 0 \\
\lambda_{4,1}^y & 0 \\
0 & \lambda_{5,2}^y \\
0 & \lambda_{6,2}^y \\
0 & \lambda_{7,2}^y \\
0 & \lambda_{8,2}^y \\
0 & \lambda_{9,2}^y
\end{bmatrix}
\begin{bmatrix}
\eta_1 \\ \eta_2
\end{bmatrix}
+
\begin{bmatrix}
\epsilon_1 \\ \epsilon_2 \\ \epsilon_3 \\ \epsilon_4 \\ \epsilon_5 \\
\epsilon_6 \\ \epsilon_7 \\ \epsilon_8 \\ \epsilon_9
\end{bmatrix}
\end{align*}
\]
3. Structural Model
The relationships between latent and observed variables:
\[
\begin{align*}
\boldsymbol{\eta} &= \mathbf{B} \boldsymbol{\eta} +
\boldsymbol{\Gamma} \boldsymbol{\xi} + \boldsymbol{\Gamma}_w \mathbf{w}
+ \boldsymbol{\zeta} \\
\begin{bmatrix}
\eta_1 \\ \eta_2
\end{bmatrix}
&=
\begin{bmatrix}
0 & 0 \\
\beta_{21} & 0
\end{bmatrix}
\begin{bmatrix}
\eta_1 \\ \eta_2
\end{bmatrix}
+
\begin{bmatrix}
\gamma_{11} & \gamma_{12} \\
\gamma_{21} & \gamma_{22}
\end{bmatrix}
\begin{bmatrix}
\xi_1 \\ \xi_2
\end{bmatrix}
+
\begin{bmatrix}
\gamma_{13} & \gamma_{14} & \gamma_{15} & \gamma_{16} &
\gamma_{17} \\
\gamma_{23} & \gamma_{24} & \gamma_{25} & \gamma_{26} &
\gamma_{27}
\end{bmatrix}
\begin{bmatrix}
w_1 \\ w_2 \\ w_3 \\ w_4 \\ w_5
\end{bmatrix}
+
\begin{bmatrix}
\zeta_1 \\ \zeta_2
\end{bmatrix}
\end{align*}
\]
4. Assumptions
- The measurement errors are uncorrelated with the latent
variables:
\[
\begin{align*}
E(\boldsymbol{\delta}|\boldsymbol{\xi}) = \mathbf{0}, \quad
E(\boldsymbol{\epsilon}|\boldsymbol{\eta}) = \mathbf{0}
\end{align*}
\]
- The structural disturbances have zero mean and are uncorrelated with
the exogenous variables:
\[
\begin{align*}
E(\boldsymbol{\zeta}) = \mathbf{0}, \quad
\text{Cov}(\boldsymbol{\zeta}, \boldsymbol{\xi}) = \mathbf{0}, \quad
\text{Cov}(\boldsymbol{\zeta}, \mathbf{w}) = \mathbf{0}
\end{align*}
\]
- The measurement errors and structural disturbances are mutually
uncorrelated:
\[
\begin{align*}
\text{Cov}(\boldsymbol{\delta}, \boldsymbol{\epsilon}) = \mathbf{0},
\quad \text{Cov}(\boldsymbol{\delta}, \boldsymbol{\zeta}) = \mathbf{0},
\quad \text{Cov}(\boldsymbol{\epsilon}, \boldsymbol{\zeta}) = \mathbf{0}
\end{align*}
\]
- The measurement errors are mutually uncorrelated:
\[
\begin{align*}
\text{Cov}(\boldsymbol{\delta}) = \boldsymbol{\Theta}_{\delta} =
\text{diag}(\theta_{\delta,1}, \dots, \theta_{\delta,7})
\end{align*}
\]
\[
\begin{align*}
\text{Cov}(\boldsymbol{\epsilon}) = \boldsymbol{\Theta}_{\epsilon} =
\text{diag}(\theta_{\epsilon,1}, \dots, \theta_{\epsilon,9})
\end{align*}
\]
- The structural disturbances have covariance matrix:
\[
\begin{align*}
\text{Cov}(\boldsymbol{\zeta}) = \boldsymbol{\Psi} =
\begin{bmatrix}
\psi_{11} & \psi_{12} \\
\psi_{21} & \psi_{22}
\end{bmatrix}
\end{align*}
\]
- The exogenous latent variables have covariance matrix:
\[
\begin{align*}
\text{Cov}(\boldsymbol{\xi}) = \boldsymbol{\Phi} =
\begin{bmatrix}
\phi_{11} & \phi_{12} \\
\phi_{21} & \phi_{22}
\end{bmatrix}
\end{align*}
\]
- The exogenous observed variables have covariance matrix:
\[
\begin{align*}
\text{Cov}(\mathbf{w}) = \boldsymbol{\Phi}_w
\end{align*}
\]
- All variables are multivariate normally distributed.
5. Implied Covariance Matrix
Let \(\boldsymbol{\theta}\)
represent all model parameters. The implied covariance matrix of the
observed variables \(\mathbf{z} =
(\mathbf{x}^T, \mathbf{y}^T, \mathbf{w}^T)^T\) is:
\[
\begin{align*}
\boldsymbol{\Sigma}(\boldsymbol{\theta}) =
\begin{bmatrix}
\boldsymbol{\Sigma}_{xx}(\boldsymbol{\theta}) &
\boldsymbol{\Sigma}_{xy}(\boldsymbol{\theta}) &
\boldsymbol{\Sigma}_{xw}(\boldsymbol{\theta}) \\
\boldsymbol{\Sigma}_{yx}(\boldsymbol{\theta}) &
\boldsymbol{\Sigma}_{yy}(\boldsymbol{\theta}) &
\boldsymbol{\Sigma}_{yw}(\boldsymbol{\theta}) \\
\boldsymbol{\Sigma}_{wx}(\boldsymbol{\theta}) &
\boldsymbol{\Sigma}_{wy}(\boldsymbol{\theta}) &
\boldsymbol{\Sigma}_{ww}(\boldsymbol{\theta})
\end{bmatrix}
\end{align*}
\]
where:
\[
\begin{align*}
\boldsymbol{\Sigma}_{xx}(\boldsymbol{\theta}) &=
\boldsymbol{\Lambda}_x \boldsymbol{\Phi} \boldsymbol{\Lambda}_x^T +
\boldsymbol{\Theta}_{\delta} \\
\boldsymbol{\Sigma}_{yy}(\boldsymbol{\theta}) &=
\boldsymbol{\Lambda}_y (\mathbf{I}-\mathbf{B})^{-1} (\boldsymbol{\Gamma}
\boldsymbol{\Phi} \boldsymbol{\Gamma}^T + \boldsymbol{\Gamma}_w
\boldsymbol{\Phi}_w \boldsymbol{\Gamma}_w^T + \boldsymbol{\Psi})
[(\mathbf{I}-\mathbf{B})^{-1}]^T \boldsymbol{\Lambda}_y^T +
\boldsymbol{\Theta}_{\epsilon} \\
\boldsymbol{\Sigma}_{ww}(\boldsymbol{\theta}) &= \boldsymbol{\Phi}_w
\\
\boldsymbol{\Sigma}_{xy}(\boldsymbol{\theta}) &=
\boldsymbol{\Lambda}_x \boldsymbol{\Phi} \boldsymbol{\Gamma}^T
[(\mathbf{I}-\mathbf{B})^{-1}]^T \boldsymbol{\Lambda}_y^T \\
\boldsymbol{\Sigma}_{xw}(\boldsymbol{\theta}) &=
\boldsymbol{\Lambda}_x \text{Cov}(\boldsymbol{\xi}, \mathbf{w}) \\
\boldsymbol{\Sigma}_{yw}(\boldsymbol{\theta}) &=
\boldsymbol{\Lambda}_y (\mathbf{I}-\mathbf{B})^{-1} (\boldsymbol{\Gamma}
\text{Cov}(\boldsymbol{\xi}, \mathbf{w}) + \boldsymbol{\Gamma}_w
\boldsymbol{\Phi}_w)
\end{align*}
\]
6. Likelihood Function
Assuming multivariate normality of the observed variables \(\mathbf{z} \sim N(\boldsymbol{\mu},
\boldsymbol{\Sigma}(\boldsymbol{\theta}))\), the likelihood
function for a sample of \(n\)
independent observations is:
\[
\begin{align*}
L(\boldsymbol{\theta}) &= \prod_{i=1}^n (2\pi)^{-p/2}
|\boldsymbol{\Sigma}(\boldsymbol{\theta})|^{-1/2}
\exp\left[-\frac{1}{2}(\mathbf{z}_i - \boldsymbol{\mu})^T
\boldsymbol{\Sigma}(\boldsymbol{\theta})^{-1} (\mathbf{z}_i -
\boldsymbol{\mu})\right]
\end{align*}
\]
where \(p = 7 + 9 + 5 = 21\) is the
total number of observed variables.
The log-likelihood function is:
\[
\begin{align*}
\ell(\boldsymbol{\theta}) &= -\frac{np}{2} \log(2\pi) - \frac{n}{2}
\log|\boldsymbol{\Sigma}(\boldsymbol{\theta})| \\
&\quad - \frac{1}{2} \sum_{i=1}^n (\mathbf{z}_i -
\boldsymbol{\mu})^T \boldsymbol{\Sigma}(\boldsymbol{\theta})^{-1}
(\mathbf{z}_i - \boldsymbol{\mu})
\end{align*}
\]
For estimation, we typically use the discrepancy function:
\[
\begin{align*}
F_{ML}(\boldsymbol{\theta}) &=
\log|\boldsymbol{\Sigma}(\boldsymbol{\theta})| + \text{tr}(\mathbf{S}
\boldsymbol{\Sigma}(\boldsymbol{\theta})^{-1}) - \log|\mathbf{S}| - p
\end{align*}
\]
where \(\mathbf{S}\) is the sample
covariance matrix.
7. Parameters to Estimate
The model parameters include:
- Factor loadings: \(\lambda_{ij}\)
in \(\boldsymbol{\Lambda}_x\) and \(\boldsymbol{\Lambda}_y\)
- Structural coefficients: \(\beta_{ij}\) in \(\mathbf{B}\), \(\gamma_{ij}\) in \(\boldsymbol{\Gamma}\), \(\gamma_{ij}^w\) in \(\boldsymbol{\Gamma}_w\)
- Variances and covariances: \(\phi_{ij}\) in \(\boldsymbol{\Phi}\), \(\psi_{ij}\) in \(\boldsymbol{\Psi}\), \(\phi_{w,ij}\) in \(\boldsymbol{\Phi}_w\)
- Measurement error variances: \(\theta_{\delta,i}\) in \(\boldsymbol{\Theta}_{\delta}\), \(\theta_{\epsilon,i}\) in \(\boldsymbol{\Theta}_{\epsilon}\)
Typically, we set one loading per latent variable to 1 for
identification.
8. Model Identification
The model is identified if:
- Each latent variable has at least 3 indicators (satisfied)
- The scale of each latent variable is set by fixing one loading to
1
- The model meets the order condition and rank condition for
identification
LS0tDQp0aXRsZTogIk1hdGhlbWF0aWNzIEFueGlldHkgU3VydmV5IFJlcG9ydCINCmF1dGhvcjogIkNoZW5nIFBlbmcgJiBMYXVyYSBQeWF0dCINCmRhdGU6ICJXZXN0IENoZXN0ZXIgVW5pdmVyc2l0eSINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgdG9jX2NvbGxhcHNlZDogeWVzDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgc21vb3RoX3Njcm9sbDogeWVzDQogICAgdGhlbWU6IGx1bWVuDQogIHBkZl9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICBmaWdfd2lkdGg6IDMNCiAgICBmaWdfaGVpZ2h0OiAzDQogIHdvcmRfZG9jdW1lbnQ6IA0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogICAgZmlnX2NhcHRpb246IHllcw0KICAgIGtlZXBfbWQ6IHllcw0KZWRpdG9yX29wdGlvbnM6IA0KICBjaHVua19vdXRwdXRfdHlwZTogaW5saW5lDQotLS0NCg0KYGBge2NzcywgZWNobyA9IEZBTFNFfQ0KI1RPQzo6YmVmb3JlIHsNCiAgY29udGVudDogIlRhYmxlIG9mIENvbnRlbnRzIjsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogIGZvbnQtc2l6ZTogMS4yZW07DQogIGRpc3BsYXk6IGJsb2NrOw0KICBjb2xvcjogbmF2eTsNCiAgbWFyZ2luLWJvdHRvbTogMTBweDsNCn0NCg0KDQpkaXYjVE9DIGxpIHsgICAgIC8qIHRhYmxlIG9mIGNvbnRlbnQgICovDQogICAgbGlzdC1zdHlsZTp1cHBlci1yb21hbjsNCiAgICBiYWNrZ3JvdW5kLWltYWdlOm5vbmU7DQogICAgYmFja2dyb3VuZC1yZXBlYXQ6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOjA7DQp9DQoNCmgxLnRpdGxlIHsgICAgLyogbGV2ZWwgMSBoZWFkZXIgb2YgdGl0bGUgICovDQogIGZvbnQtc2l6ZTogMjJweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogIGNvbG9yOiBEYXJrUmVkOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQogIGZvbnQtZmFtaWx5OiAiR2lsbCBTYW5zIiwgc2Fucy1zZXJpZjsNCn0NCg0KaDQuYXV0aG9yIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgZm9udC1zaXplOiAxNXB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1mYW1pbHk6IHN5c3RlbS11aTsNCiAgY29sb3I6IG5hdnk7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCg0KaDQuZGF0ZSB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogIGZvbnQtc2l6ZTogMThweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogIGZvbnQtZmFtaWx5OiAiR2lsbCBTYW5zIiwgc2Fucy1zZXJpZjsNCiAgY29sb3I6IERhcmtCbHVlOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQoNCmgxIHsgLyogSGVhZGVyIDEgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDIwcHg7DQogICAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IGRhcmtyZWQ7DQogICAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KDQpoMiB7IC8qIEhlYWRlciAyIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxOHB4Ow0KICAgIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBuYXZ5Ow0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCmgzIHsgLyogSGVhZGVyIDMgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE2cHg7DQogICAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KaDQgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMTRweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IGRhcmtyZWQ7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KLyogQWRkIGRvdHMgYWZ0ZXIgbnVtYmVyZWQgaGVhZGVycyAqLw0KLmhlYWRlci1zZWN0aW9uLW51bWJlcjo6YWZ0ZXIgew0KICBjb250ZW50OiAiLiI7DQoNCmJvZHkgeyBiYWNrZ3JvdW5kLWNvbG9yOndoaXRlOyB9DQoNCi5oaWdobGlnaHRtZSB7IGJhY2tncm91bmQtY29sb3I6eWVsbG93OyB9DQoNCnAgeyBiYWNrZ3JvdW5kLWNvbG9yOndoaXRlOyB9DQoNCn0NCmBgYA0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCiMgY29kZSBjaHVuayBzcGVjaWZpZXMgd2hldGhlciB0aGUgUiBjb2RlLCB3YXJuaW5ncywgYW5kIG91dHB1dCANCiMgd2lsbCBiZSBpbmNsdWRlZCBpbiB0aGUgb3V0cHV0IGZpbGVzLg0KaWYgKCFyZXF1aXJlKCJrbml0ciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJrbml0ciIpDQogICBsaWJyYXJ5KGtuaXRyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJwYW5kZXIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygicGFuZGVyIikNCiAgIGxpYnJhcnkocGFuZGVyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJ0aWR5dmVyc2UiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIikNCmxpYnJhcnkodGlkeXZlcnNlKQ0KfQ0KaWYgKCFyZXF1aXJlKCJHR2FsbHkiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygiR0dhbGx5IikNCmxpYnJhcnkoR0dhbGx5KQ0KfQ0KIyBJbnN0YWxsIGFuZCBsb2FkIHRoZSBwYWNrYWdlDQppZiAoIXJlcXVpcmUoImljYSIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoImljYSIpDQpsaWJyYXJ5KGljYSkNCn0NCmlmICghcmVxdWlyZSgiZmFzdElDQSIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoImZhc3RJQ0EiKQ0KICBsaWJyYXJ5KGZhc3RJQ0EpDQp9DQppZiAoIXJlcXVpcmUoIk1BU1MiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJNQVNTIikNCiAgbGlicmFyeShNQVNTKQ0KfQ0KaWYgKCFyZXF1aXJlKCJnZ3Bsb3QyIikpIHsNCiAgaW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIpDQogIGxpYnJhcnkoZ2dwbG90MikNCn0gDQppZiAoIXJlcXVpcmUoInBsb3RseSIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoInBsb3RseSIpDQogIGxpYnJhcnkocGxvdGx5KQ0KfSANCmlmICghcmVxdWlyZSgibGF2YWFuIikpIHsNCiAgaW5zdGFsbC5wYWNrYWdlcygibGF2YWFuIikNCiAgbGlicmFyeShsYXZhYW4pDQp9IA0KaWYgKCFyZXF1aXJlKCJzZW1Ub29scyIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoInNlbVRvb2xzIikNCiAgbGlicmFyeShzZW1Ub29scykNCn0NCmlmICghcmVxdWlyZSgic3RyaW5nciIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoInN0cmluZ3IiKQ0KICBsaWJyYXJ5KHN0cmluZ3IpDQp9DQppZiAoIXJlcXVpcmUoInJlc2hhcGUyIikpIHsNCiAgaW5zdGFsbC5wYWNrYWdlcygicmVzaGFwZTIiKQ0KICBsaWJyYXJ5KHJlc2hhcGUyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJwc3ljaCIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoInBzeWNoIikNCiAgbGlicmFyeShwc3ljaCkNCn0NCmlmICghcmVxdWlyZSgiZ2dyaWRnZXMiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJnZ3JpZGdlcyIpDQogIGxpYnJhcnkoZ2dyaWRnZXMpDQp9DQppZiAoIXJlcXVpcmUoIlJDb2xvckJyZXdlciIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoIlJDb2xvckJyZXdlciIpDQogIGxpYnJhcnkoUkNvbG9yQnJld2VyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJoZWF0bWFwbHkiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJoZWF0bWFwbHkiKQ0KICBsaWJyYXJ5KGhlYXRtYXBseSkNCn0NCmlmICghcmVxdWlyZSgic2VtUGxvdCIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoInNlbVBsb3QiKQ0KICBsaWJyYXJ5KHNlbVBsb3QpDQp9DQppZiAoIXJlcXVpcmUoImxhdmFhblBsb3QiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJsYXZhYW5QbG90IikNCiAgbGlicmFyeShsYXZhYW5QbG90KQ0KfQ0KaWYgKCFyZXF1aXJlKCJib290IikpIHsNCiAgaW5zdGFsbC5wYWNrYWdlcygiYm9vdCIpDQogIGxpYnJhcnkoYm9vdCkNCn0NCmlmICghcmVxdWlyZSgibGVhcHMiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJsZWFwcyIpDQogIGxpYnJhcnkobGVhcHMpDQp9DQojIyBsaWJyYXJ5KGxlYXBzKQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCAgICAgICAjIGluY2x1ZGUgY29kZSBjaHVuayBpbiB0aGUgb3V0cHV0IGZpbGUNCiAgICAgICAgICAgICAgICAgICAgICB3YXJuaW5nID0gRkFMU0UsICAgIyBzb21ldGltZXMsIHlvdSBjb2RlIG1heSBwcm9kdWNlIHdhcm5pbmcgbWVzc2FnZXMsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgeW91IGNhbiBjaG9vc2UgdG8gaW5jbHVkZSB0aGUgd2FybmluZyBtZXNzYWdlcyBpbg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHRoZSBvdXRwdXQgZmlsZS4gDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IFRSVUUsICAgICMgeW91IGNhbiBhbHNvIGRlY2lkZSB3aGV0aGVyIHRvIGluY2x1ZGUgdGhlIG91dHB1dA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGluIHRoZSBvdXRwdXQgZmlsZS4NCiAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgY29tbWVudCA9IE5BDQogICAgICAgICAgICAgICAgICAgICAgKSAgDQpgYGANCg0KXA0KDQojIEludHJvZHVjdGlvbg0KDQpUaGUgc3ViamVjdCBvZiBtYXRoZW1hdGljcyBjYXVzZXMgZmVhciBhbmQgZGlmZmljdWx0eSBmb3IgYSB3aWRlIHJhbmdlIG9mIHN0dWRlbnRzLiBXZSBvZnRlbiBoZWFyIHN0dWRlbnRzIGNsYWltLCDigJxJIGRvbuKAmXQgbGlrZSBtYXRo4oCdLCDigJxJ4oCZbSBqdXN0IG5vdCBnb29kIGF0IG1hdGjigJ0sIOKAnEnigJltIG5vdCBhIG1hdGggcGVyc29u4oCdLCBvciDigJxJIHdhc27igJl0IGJvcm4gd2l0aCB0aGUgbWF0aCBnZW5l4oCdLCBldGMuIEFsdGhvdWdoIHRoZXNlIGNsYWltcyBhcmUgbm90IHBlcmZlY3QgaW5kaWNhdG9ycyBvZiBtYXRoIGFueGlldHksIHN0dWRlbnRzIHdobyBoYXZlIHRoZXNlIGZpeGVkIG1pbmRzZXRzIHdpbGwgYmUgbW9yZSBsaWtlbHkgdG8gZXhwZXJpZW5jZSBtYXRoIGFueGlldHkuDQoNCldoaWxlIG1hdGggYW54aWV0eSBjYW4gaGF2ZSBhIHNlcmlvdXMgaW1wYWN0IG9uIGFjYWRlbWljIHBlcmZvcm1hbmNlLCBpdCBkb2VzIG5vdCBtZWFuIGEgbGFjayBvZiBtYXRoZW1hdGljcyBhYmlsaXR5LiBQcm9mLiBMYXVyZW50IFNjaHdhcnR6IGV4cGVyaWVuY2VkIG1hdGggYW54aWV0eSBpbiB0aGUgMTF0aCBncmFkZSwgYnV0IHRoaXMgZGlkIG5vdCBwcmV2ZW50IGhpbSBmcm9tIGJlY29taW5nIGEgcHJvbWluZW50IG1hdGhlbWF0aWNpYW4uIEluIGZhY3QsIGhlIHdvbiB0aGUgRmllbGRzIE1vZGVsICh0aGUgbWF0aGVtYXRpY2lhbuKAmXMgTm9iZWwgUHJpemUpIGluIDE5NTAuIEVmZmVjdGl2ZWx5IG1hbmFnaW5nIG1hdGggYW54aWV0eSByZXF1aXJlcyBhIGRlZXAgdW5kZXJzdGFuZGluZyBvZiBtYXRoIGFueGlldHkuDQoNClRoaXMgcHJvamVjdCBhaW1zIHRvIGlkZW50aWZ5IGZhY3RvcnMgdGhhdCBhcmUgc3Ryb25nbHkgYXNzb2NpYXRlZCB3aXRoIG1hdGggYW54aWV0eSBhbmQgdXNlIHRoZW0gdG8gcmVkdWNlIG1hdGggYW54aWV0eSBhbmQsIGNvbnNlcXVlbnRseSwgaW1wcm92ZSBhY2FkZW1pYyBwZXJmb3JtYW5jZS4gU3BlY2lmaWNhbGx5Og0KDQoxLglUaGUgcmVzdWx0cyBvZiB0aGlzIHByb2plY3Qgd2lsbCBjb250cmlidXRlIHRvIHRoZSBib2R5IG9mIGV4aXN0aW5nIGtub3dsZWRnZS4NCg0KMi4JSWRlbnRpZmljYXRpb24gb2YgZW52aXJvbm1lbnRhbCBmYWN0b3JzIGFpZHMgdGhlIGRldmVsb3BtZW50IG9mIGludGVydmVudGlvbiB0b29scyBmb3IgZWR1Y2F0b3JzIGFuZCBzdXBwb3J0IHN0YWZmIHRvIGhlbHAgc3R1ZGVudHMgcmVkdWNlIG1hdGggYW54aWV0eSBhbmQgaW1wcm92ZSB0aGVpciBhY2FkZW1pYyBwZXJmb3JtYW5jZS4NCg0KMy4JVGhlIG91dGNvbWVzIG9mIHRoaXMgcHJvamVjdCBjYW4gYmUgdXNlZCB0byBpbXBsaWNpdGx5IGltcHJvdmUgcmV0ZW50aW9uLg0KDQojIExpdGVyYXR1cmUgUmV2aWV3DQoNCk1hdGhlbWF0aWNzIGFueGlldHkgaW52b2x2ZXMgZmVlbGluZ3Mgb2YgZmVhciwgdGVuc2lvbiwgYXBwcmVoZW5zaW9uLCBhbmQgcGh5c2lvbG9naWNhbCByZWFjdGl2aXR5IGludGVyZmVyaW5nIHdoZW4gaW5kaXZpZHVhbHMgZW5nYWdlIHdpdGggbnVtYmVyIG1hbmlwdWxhdGlvbiBhbmQgbWF0aGVtYXRpY2FsIHByb2JsZW0tc29sdmluZyAoc2VlLCBmb3IgZXhhbXBsZSwgUGxldHplciBldCBhbC4gMjAxNikuIEluIHRoZSBVLlMuLCBhbiBlc3RpbWF0ZWQgMjUlIG9mIGZvdXIteWVhciBjb2xsZWdlIHN0dWRlbnRzIGFuZCB1cCB0byA4MCUgb2YgY29tbXVuaXR5IGNvbGxlZ2Ugc3R1ZGVudHMgc3VmZmVyIGZyb20gYSBtb2RlcmF0ZSB0byBhIGhpZ2ggZGVncmVlIG9mIG1hdGhlbWF0aWNzIGFueGlldHkgKENoYW5nICYgQmVpbG9jaywgMjAxNikuIFRoZSBmcmVxdWVuY3kgb2YgbmVnYXRpdmUgZWZmZWN0cyBvZiBtYXRoIGFueGlldHkgb24gY29sbGVnZSBzdHVkZW50cyBpcyBpbmNyZWFzaW5nLg0KDQpUaGUgZWFybGllc3QgcmVzZWFyY2ggb24gbWF0aCBhbnhpZXR5IGNhbiBiZSB0cmFjZWQgYmFjayB0byBHb3VnaCAoMTk1NCkgd2hvIHVzZWQgdGhlIHRlcm0gbWF0aGVtYXBob2JpYS4gVGhlIHRlcm0gbWF0aCBhbnhpZXR5IHdhcyBmaXJzdCB1c2VkIGJ5IERyZWdlciBhbmQgQWlrZW4gKDE5NTcpLiBUaGUgZmlyc3QgZGVmaW5pdGlvbiBvZiBtYXRoIGFueGlldHkgaXMgY3JlZGl0ZWQgdG8gUmljaGFyZHNvbiBhbmQgU3Vpbm4gKDE5NzIpLCB3aG8gZGVzY3JpYmVkIG1hdGggYW54aWV0eSBhcyDigJxmZWVsaW5ncyBvZiB0ZW5zaW9uIGFuZCBhbnhpZXR5IHRoYXQgaW50ZXJmZXJlIHdpdGggdGhlIG1hbmlwdWxhdGlvbiBvZiBudW1iZXJzIGFuZCBzb2x2aW5nIG9mIG1hdGhlbWF0aWNhbCBwcm9ibGVtcyBpbiBhIHdpZGUgdmFyaWV0eSBvZiBvcmRpbmFyeSBsaWZlIGFuZCBhY2FkZW1pYyBzaXR1YXRpb25z4oCdLiAgDQoNCkluIHRoZSBwYXN0IDcwIHllYXJzLCBudW1lcm91cyBhdXRob3JzIGNvbmR1Y3RlZCBleHRlbnNpdmUgcmVzZWFyY2ggb24gbWF0aCBhbnhpZXR5LiBQYXJ0aWN1bGFybHksIGluIHRoZSBwYXN0IDIwIHllYXJzLCByZXNlYXJjaGVycyBmcm9tIGRpZmZlcmVudCBkaXNjaXBsaW5lcyBpbmNsdWRpbmcgbWF0aGVtYXRpY3MgaGF2ZSBpbnZlc3RpZ2F0ZWQgdGhlIGFzc29jaWF0aW9uIGJldHdlZW4gbWF0aCBhbnhpZXR5IGFuZCBtYXRoIGFjaGlldmVtZW50LCB0aGUgY2F1c2VzIG9mIG1hdGggYW54aWV0eSwgY2hhcmFjdGVyaXN0aWNzIG9mIHN0dWRlbnRzIHRoYXQgaW5jcmVhc2Ugc3VzY2VwdGliaWxpdHkgdG8gbWF0aCBhbnhpZXR5LCBhbmQgZWZmb3J0cyB0aGF0IGVkdWNhdG9ycyBjYW4gdGFrZSB0byByZW1lZHkgaXQuDQoNCk1hdGggYW54aWV0eSBpcyByZWFsLiBJdHMgbmVnYXRpdmUgaW1wYWN0IG9uIHN0dWRlbnRz4oCZIGFjYWRlbWljIHBlcmZvcm1hbmNlIGFuZCB0aGVpciBmdXR1cmUgcHJvZmVzc2lvbmFsIGxpZmUgaXMgcHJvZm91bmQuIEV4dGVuc2l2ZSByZXNlYXJjaCBwdWJsaWNhdGlvbnMgc2luY2UgMjAwMCBoYXZlIHNob3duIHRoYXQgbWF0aCBhbnhpZXR5IHJlbGF0ZXMgaW52ZXJzZWx5IHRvIHBvc2l0aXZlIGF0dGl0dWRlcyB0b3dhcmQgbWF0aGVtYXRpY3MgYW5kIGlzIGJvdW5kIGRpcmVjdGx5IHRvIGF2b2lkYW5jZSBvZiB0aGUgc3ViamVjdCAoc2VlIGZvciBleGFtcGxlLCBTZWdvb2wgZXQgYWwuLCAyMDEzKS4gSXQgYWZmZWN0cyBib3RoIG1hdGggYW5kIG92ZXJhbGwgYWNhZGVtaWMgcGVyZm9ybWFuY2Ugc2luY2UgbWF0aCBhbnhpZXR5IGxlYWRzIHRvIHRoZSBkcmFpbmFnZSBvZiBjb2duaXRpdmUgcmVzb3VyY2VzLCBtb3RpdmF0aW9uIHJlZHVjdGlvbiwgYW5kIHN0cmF0ZWd5IGltcGFpcm1lbnQgKEtsZWUgZXQgYWwuLCAyMDIyKS4NCg0KTWF0aCBhbnhpZXR5IGNhbiBhbHNvIGxlYWQgdG8gcG9vciBhY2FkZW1pYyBwZXJmb3JtYW5jZSBhbmQgY291cnNlIHdpdGhkcmF3YWwsIHB1dHRpbmcgc3R1ZGVudHMgYmVoaW5kIHNjaGVkdWxlIGFuZCBpbmNyZWFzaW5nIHRoZSByaXNrIG9mIGRyb3Agb3V0LCB3aGljaCByZWR1Y2VzIHN0dWRlbnQgcmV0ZW50aW9uIHJhdGVzLiBXaWxzb24gKDIwMTMpIHN0dWRpZWQgbWF0aCBhbnhpZXR5IG9mIG1hdHVyZS1hZ2UgcHJlLXNlcnZpY2UgdGVhY2hlcnMgYXMgYSBwb3RlbnRpYWwgY29udHJpYnV0aW5nIGZhY3RvciB0aGF0IGltcGFjdHMgc3R1ZGVudCByZXRlbnRpb24uIERha2VyIGV0IGFsLiAoMjAyMSkgcmVjZW50bHkgc3R1ZGllZCB0aGUgaW1wYWN0IG9mIG1hdGggYW54aWV0eSBvbiBmaXJzdC15ZWFyIFNURU0gc3R1ZGVudHMgYW5kIGNvbmNsdWRlZCB0aGF0IG1hdGggYW54aWV0eSBwcmVkaWN0cyBTVEVNIGF2b2lkYW5jZSBhbmQgdW5kZXJwZXJmb3JtYW5jZSB0aHJvdWdob3V0IHRoZSB1bml2ZXJzaXR5LCBpbmRlcGVuZGVudGx5IG9mIG1hdGggYWJpbGl0eS4NCg0KQSB3ZWFsdGggb2YgZW1waXJpY2FsIHN0dWRpZXMgb24gdmFyaW91cyBhc3BlY3RzIG9mIG1hdGggYW54aWV0eSBoYXZlIGJlZW4gY29uZHVjdGVkIHNpbmNlIERyZWdlciAmIEFpa2Vu4oCZcyAoMTk1Nykgc2VtaW5hbCB3b3JrLiBEdWUgdG8gdGhlIGNvbXBsZXggcGF0aHdheXMgdG93YXJkIHRoZSBkZXZlbG9wbWVudCBvZiBtYXRoIGFueGlldHkgYW5kIGl0cyBsaW5rcyB3aXRoIGFjaGlldmVtZW50cyBhbmQgY29uZm91bmRlcnMsIHRoZSBvcmlnaW5zIGFuZCBvdXRjb21lcyBvZiBtYXRoIGFueGlldHkgYXJlIHN0aWxsIG5vdCBmdWxseSB1bmRlcnN0b29kLg0KDQpSZWNlbnQgYW5kIG9uZ29pbmcgcmVzZWFyY2ggZm9jdXNlcyBvbiB0aGUgZGV2ZWxvcG1lbnQgYW5kIGR5bmFtaWMgaW50ZXJwbGF5IGJldHdlZW4gZmFjdG9ycyB0aGF0IGNhdXNlIG1hdGggYW54aWV0eS4gTW9zdCBvZiB0aGUgcmVzZWFyY2ggY2FuIGJlIGNsYXNzaWZpZWQgaW50byB0aHJlZSBjYXRlZ29yaWVzOiBzaXR1YXRpb25hbCwgZGlzcG9zaXRpb25hbCwgYW5kIGVudmlyb25tZW50YWwgKE/igJlMZWFyeSBldCBhbC4sIDIwMTcpLiBUaGUgY3VycmVudCBwcm9qZWN0IHdpbGwgZXhwbG9yZSBhbGwgdGhyZWUgdHlwZXMgb2YgZmFjdG9ycywgYnV0IHRoZSBwcmltYXJ5IGZvY3VzIGlzIG9uIHRoZSBlbnZpcm9ubWVudGFsIGZhY3RvcnMgc3VjaCBhcyBwcmlvciBwZXJjZXB0aW9ucywgYXR0aXR1ZGVzLCBhbmQgZXhwZXJpZW5jZXMgdGhhdCBoYXZlIGFmZmVjdGVkIHRoZSBpbmRpdmlkdWFsLg0KDQojIFJlc2VhcmNoIE9iamVjdGl2ZXMNCg0KU2luY2UgbG93ZXIgbWF0aGVtYXRpY3MgYWNoaWV2ZW1lbnQgcHJlZGljdHMgaGlnaGVyIHN1YnNlcXVlbnQgbWF0aCBhbnhpZXR5IGFuZCBoaWdoZXIgbWF0aCBhbnhpZXR5IHByZWRpY3RzIGxvd2VyIGZ1dHVyZSBhY2hpZXZlbWVudCwgcmVkdWNpbmcgbWF0aCBhbnhpZXR5IHdpbGwgaGVscCBzdHVkZW50cyBkZXZlbG9wIGEgcG9zaXRpdmUgYXR0aXR1ZGUgdG8gbWF0aGVtYXRpY3MsIGJ1aWxkIGNvbmZpZGVuY2UsIGJvb3N0IG1vdGl2YXRpb24sIGFuZCBjb25zZXF1ZW50bHkgaW1wcm92ZSB0aGVpciBhY2hpZXZlbWVudHMuIFRoaXMgc3R1ZHkgYWltZWQgdG8gaWRlbnRpZnkgdGhlIGZhY3RvcnMgdGhhdCBjYW4gcmVkdWNlIG1hdGggYW54aWV0eSBpbiBjb2xsZWdlIHN0dWRlbnRzLiBTcGVjaWZpYyBvYmplY3RpdmVzIGFyZQ0KDQoqKk9iamVjdGl2ZSAxKio6IEFkb3B0aW5nIHdlbGwtZXN0YWJsaXNoZWQgcHN5Y2hvbWV0cmljIHN1cnZleSBpbnN0cnVtZW50cyBBTUFTIGFuZCBzZWxmLWVmZmljYWN5IGluc3RydW1lbnRzIHRvIGNvbGxlY3QgbWF0aCBhbnhpZXR5IGFuZCBzZWxmLWVmZmljYWN5IGRhdGEuDQoNCioqT2JqZWN0aXZlIDIqKjogSW5jbHVkZSBzb21lIGRlbW9ncmFwaGljIGNoYXJhY3RlcmlzdGljcyBzdWNoIGFzIGFnZSBhbmQgZ2VuZGVyIHRvIGNvbXBhcmUgdGhlIHJlc3VsdHMgd2l0aCB0aGF0IG9mIGV4aXN0aW5nIHJlc2VhcmNoIGFuZCB1c2UgdGhlbSBhcyBhIGJhc2VsaW5lLg0KDQoqKk9iamVjdGl2ZSAzKio6IFRlYWNoaW5nIHN0cmF0ZWdpZXMgY2FuIHJlZHVjZSBtYXRoIGFueGlldHkgYW5kIGltcHJvdmUgbGVhcm5pbmcgb3V0Y29tZXMuIFdlIHdpbGwgaW52ZXN0aWdhdGUgc2V2ZXJhbCBkaWZmZXJlbnQgc3RyYXRlZ2llcyBpbiBtYXRoZW1hdGljcyB0ZWFjaGluZyBzdWNoIGFzIGNvbmNlcHR1YWwsIHByb2NlZHVyZSwgZXRjLiwgdG8gc2VlIGlmIHRoZXNlIHN0cmF0ZWdpZXMgYWZmZWN0IHRoZSBsZXZlbCBvZiBtYXRoIGFueGlldHkuDQoNCioqT2JqZWN0aXZlIDQqKjogRWZmZWN0aXZlbHkgdXNpbmcgdGhlIHRlY2hub2xvZ2llcyBjYW4gcmVkdWNlIG1hdGggYW54aWV0eS4gVGhlIHJlY2VudGx5IGRldmVsb3BlZCBlZHVjYXRpb25hbCB0ZWNobm9sb2dpZXMgZHVyaW5nIHRoZSBwYW5kZW1pYyBoYXZlIG5vdCBiZWVuIGRpc2N1c3NlZCBpbiB0aGUgbGl0ZXJhdHVyZSBvbiBtYXRoIGFueGlldHkuIFdlIHdpbGwgaW52ZXN0aWdhdGUgaG93IHRoZXNlIG5ldyB0ZWNobm9sb2dpZXMgYWZmZWN0IG1hdGggYW54aWV0eS4NCg0KKipPYmplY3RpdmUgNSoqOiBMZWFybmluZyBtb2RhbGl0aWVzIGFuZCBzdHlsZXMgYXJlIGFsc28gYXNzb2NpYXRlZCB3aXRoIG1hdGggYW54aWV0eS4gTW9zdCBvZiB0aGUgcmVzZWFyY2ggaW4gdGhpcyBkaXJlY3Rpb24gaXMgYmFzZWQgb24gaGlnaCBzY2hvb2wgc3R1ZGVudHMuIFdlIHdpbGwgZXhwbG9yZSBob3cgdGhlc2UgbGVhcm5pbmcgbW9kYWxpdGllcyBhbmQgc3R5bGVzIGFmZmVjdCBtYXRoIGFueGlldHkgYW1vbmcgY29sbGVnZSBzdHVkZW50cy4NCg0KKipPYmplY3RpdmUgNioqOiBDcmVhdGluZyBhbmQgdXNpbmcgY2FtcHVzIGxlYXJuaW5nIHJlc291cmNlcyBjYW4gcmVkdWNlIG1hdGggYW54aWV0eSBhbmQgaW1wcm92ZSB0aGVpciBhY2FkZW1pYyBwZXJmb3JtYW5jZSAoTW9saW5lciAmIEFsZWdyZSwgMjAyMCkuIFdlIHdpbGwgZXhwbG9yZSB3aGV0aGVyIGFuZCBob3cgbGVhcm5pbmcgcmVzb3VyY2VzIG9uIGNvbGxlZ2UgY2FtcHVzZXMgcmVkdWNlIGFueGlldHkuDQoNCg0KDQojIE1hdGVyaWFscw0KDQojIyBQYXJ0aWNpcGFudHMNCg0KVGhlIHN1cnZleSB3YXMgYXBwcm92ZWQgYnkgV0NVJ3MgSVJCLiBXZSBpbnZpdGUgYWxsIFdDVSBzdHVkZW50cyB3aG8gdGFrZSB0aGVpciBmaXJzdCBXQ1UgbWF0aGVtYXRpY3MgYW5kIHN0YXRpc3RpY3MgY2xhc3MgaW4gdGhlIGZhbGwgc2VtZXN0ZXJzIG9mIDIwMjQgYW5kIHRoZSBzcHJpbmcgc2VtZXN0ZXIgb2YgMjAyNS4gUGFydGljaXBhdGlvbiBpbiB0aGUgc3R1ZHkgYXJlIHZvbHVudGFyeSBhbmQgcmVzcG9uc2VzIHJlbWFpbiBhbm9ueW1vdXMuIFRoZSBkYXRhIHdhcyBjb2xsZWN0ZWQgaW4gdGhlIHNwcmluZyBhbmQgZmFsbCBzZW1lc3RlcnMgb2YgMjAyNCBiYXNlZCBvbiB0aGUgcHJvdG9jb2xzIHNldCBieSBXQ1XigJlzIEluc3RpdHV0aW9uYWwgUmVzZWFyY2guIFZpYSBRdWFsdHJpY3MsIHdlIHNlbnQgYW4gaW52aXRhdGlvbiBlbWFpbCB0byBhbGwgcXVhbGlmaWVkIHN0dWRlbnRzIHNwcmluZyBhbmQgZmFsbCBtaWQtc2VtZXN0ZXIuIEEgcmVtaW5kZXIgZW1haWwgd2FzIHNlbnQgYXQgdGhlIGVuZCBvZiB0aGUgc2VtZXN0ZXIgdG8gbm9uLXJlc3BvbmRpbmcgc3R1ZGVudHMgdG8gYm9vc3QgdGhlIHBhcnRpY2lwYXRpb24gcmF0ZS4gQSAkMTAgQW1hem9uIGdpZnQgY2FyZCB3YXMgb2ZmZXJlZCB0byBzdXJ2ZXkgY29tcGxldGVycyBhbmQgZGlzdHJpYnV0ZWQgdGhyb3VnaCBRdWFsdHJpY3Mgc28gYW5vbnltaXR5IGlzIGd1YXJhbnRlZWQuDQoNClRoZSBzdHVkeSBwb3B1bGF0aW9uIGluIHRoaXMgc3R1ZHkgaXMgZGVmaW5lZCBhcyBXQ1Ugc3R1ZGVudHMgYWdlZCAxOCB5ZWFycyBvciBvbGRlciB3aG8gdG9vayB0aGVpciBmaXJzdCBNQVQgY2xhc3MgYXQgV0NVLiBUaGUgcmVzdWx0cyBpbiB0aGlzIHN0dWR5IGNhbiBiZSBnZW5lcmFsaXplZCB0byBzaW1pbGFyIHJlZ2lvbmFsIHVuaXZlcnNpdGllcyBhbmQgdGhvc2UgcmVjZW50bHkgcmVjbGFzc2lmaWVkIFIyIGluc3RpdHV0aW9ucy4NCg0KIyMgU3VydmV5IEluc3RydW1lbnRzDQoNClRoZSBzdXJ2ZXkgd2lsbCBoYXZlIHRocmVlIGNvbXBvbmVudHM6DQoNCjEuCSoqTXVsdGktaXRlbSBTdXJ2ZXkgSW5zdHJ1bWVudCBNYXRoIEFueGlldHkqKjogQU1BUy4gV2Ugd2lsbCB1c2UgdGhlIGZyZXF1ZW50bHkgdXNlZCBBTUFTIHdpdGggbmluZSBpdGVtcyBjb250cmlidXRpbmcgdG8gdHdvIHNjYWxlczogTWF0aCBMZWFybmluZyBhbmQgTWF0aCBUZXN0aW5nLiBBTUFTIG9yaWdpbmF0ZXMgZnJvbSBhIHJlYW5hbHlzaXMgb2YgYSBNQVJTLVIgYnkgSG9wa28gZXQgYWwuICgyMDAzKS4gQU1BUyBpcyBzaG9ydCAoY29tcGxldGlvbiB0YWtlcyBhYm91dCA1IG1pbnV0ZXMpIGFuZCBoYXMgZ29vZCBwc3ljaG9tZXRyaWMgcHJvcGVydGllczogaGlnaCByZWxpYWJpbGl0eSBhcyBtZWFzdXJlZCBieSBpbnRlcm5hbCBjb25zaXN0ZW5jeSBhbmQgdGVzdC1yZXRlc3QgbWV0aG9kLCBjb25zdHJ1Y3QgdmFsaWRpdHkgYXMgbWVhc3VyZWQgYnkgZXhwbG9yYXRvcnkgYW5kIGNvbmZpcm1hdG9yeSBmYWN0b3IgYW5hbHlzZXMsIGFuZCBjb252ZXJnZW50IGFuZCBkaXNjcmltaW5hbnQgdmFsaWRpdHkuIChOdW1lcm91cyBzdWJzZXF1ZW50IHN0dWRpZXMgaGF2ZSBjb25maXJtZWQgdGhlc2UgcmVzdWx0cy4pIFdlIHdpbGwgdXNlIEFNQVMgdG8gbWVhc3VyZSBtYXRoIGFueGlldHkgaW4gdGhpcyBwcm9qZWN0Lg0KDQoyLgkqKk11bHRpLWl0ZW0gU3VydmV5IEluc3RydW1lbnQgZm9yIE1hdGggU2VsZi1lZmZpY2FjeSoqLiBNYXRoIGFueGlldHkgYW5kIG1hdGggc2VsZi1lZmZpY2FjeSBhcmUgbmVnYXRpdmVseSBjb3JyZWxhdGVkLiBUaGUgdGhyZWUtaXRlbSBzaG9ydCB2ZXJzaW9uIG9mIG1hdGggc2VsZi1lZmZpY2FjeSBxdWVzdGlvbm5haXJlczogKDEpIEkgdXN1YWxseSB1bmRlcnN0YW5kIGEgbWF0aGVtYXRpY2FsIGlkZWEgcXVpY2tseTsgKDIpIEkgaGF2ZSB0byB3b3JrIHZlcnkgaGFyZCB0byB1bmRlcnN0YW5kIG1hdGhlbWF0aWNzOyAoMykgSSBjYW4gY29ubmVjdCBtYXRoZW1hdGljYWwgaWRlYXMgdGhhdCBJIGhhdmUgbGVhcm5lZDsgdXNlZCBieSBSb3pnb25qdWsgZXQgYWwuICgyMDIwKS4NCg0KMy4gKipNdWx0aS1pdGVtIFN1cnZleSBJbnN0cnVtZW50IGZvciBTdHVkZW50J3MgUGVyY2VwdGlvbiBvbiBGYWN1bHR5IFRlYWNoaW5nIFN0cmF0ZWdpZXMqKjogU3R1ZGVudHMnIG1hdGhlbWF0aWNzIGFueGlldHkgaXMgZGlyZWN0bHkgaW5mbHVlbmNlZCBieSB0aGVpciBpbnN0cnVjdG9ycycgdGVhY2hpbmcgc3RyYXRlZ2llcy4gVGhpcyBzdHVkeSBlbXBsb3lzIHRoZSBUZWFjaGluZyBTdHJhdGVnaWVzIEludmVudG9yeSB1c2VkIGJ5IENhcmRpbm8gSnIuIGFuZCBPcnRlZ2EtRGVsYSBDcnV6ICgyMDIwKSB0byBhc3Nlc3Mgc3R1ZGVudHMnIHBlcmNlcHRpb25zIG9mIHRoZXNlIHN0cmF0ZWdpZXMuIFRoZSBpbnZlbnRvcnkgY29tcHJpc2VzIGVpZ2h0IGRpc3RpbmN0IGRpbWVuc2lvbnMgKHN1YnNjYWxlcykuDQoNCg0KNC4gKipNdWx0aS1pdGVtIFN1cnZleSBJbnN0cnVtZW50IGZvciBTdHVkZW50IExlYXJuaW5nIE1vZGFsaXRpZXMqKjogQVZJRCAoQWR2YW5jZW1lbnQgVmlhIEluZGl2aWR1YWwgRGV0ZXJtaW5hdGlvbikgaXMgYSBwcm9ncmFtIGludHJvZHVjZWQgYnkgTWVhZG93bGFyayBFbGVtZW50YXJ5IFNjaG9vbCB0aGF0IGFpbXMgdG8gY2xvc2UgdGhlIGFjaGlldmVtZW50IGdhcCBieSBwcmVwYXJpbmcgYWxsIHN0dWRlbnRzIGZvciBjb2xsZWdlIHJlYWRpbmVzcyBhbmQgc3VjY2VzcyBpbiBhIGdsb2JhbCBzb2NpZXR5LiBXZSB1c2VkIEFWSUQncyBTdHVkZW50IExlYXJuaW5nIE1vZGFsaXR5IEludmVudG9yeSB0byBpZGVudGlmeSBzdHVkZW50IGxlYXJuaW5nIHN0eWxlcyAoYXVkaXRvcnksIHZpc3VhbCwgYW5kIGtpbmVzdGhldGljKSBpbiB0aGlzIHN0dWR5LiBUaGUgaW52ZW50b3J5IGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9wZW5nZHNjaS5naXRodWIuaW8vTWF0aEFueGlldHkvQVZJRF9MZWFybmluZ19TdHlsZV9JbnZlbnRvcnkucGRmPi4NCg0KDQo1LiAqKk11bHRpLWl0ZW0gU3VydmV5IEluc3RydW1lbnQgZm9yIFN0dWRlbnQncyBFbmdhZ2VtZW50Kio6IFdlIHNlbGVjdCAxMiBxdWVzdGlvbm5haXJlcyBmcm9tIHRoZSBOU1NFIChOYXRpb25hbCBTdXJ2ZXkgb2YgU3R1ZGVudCBFbmdhZ2VtZW50KSB0byBhc3Nlc3Mgc3R1ZGVudHMgaW4tY2xhc3MgYW5kIGFmdGVyLWNsYXNzIGVuZ2FnZW1lbnQgYW5kIHVzZSBvZiBsZWFybmluZyByZXNvdXJjZXMuIFRoZSBUaGUgY29yZSBOU1NFIHN1cnZleSBmb3IgYSBmaXJzdC15ZWFyIG9yIHNlbmlvciBzdHVkZW50IGNvbnNpc3RzIG9mIGFwcHJveGltYXRlbHkgNDAgdG8gNTAgcmVxdWlyZWQgaXRlbXMsIGJ1dCB0aGUgdG90YWwgYmFuayBvZiBwb3RlbnRpYWwgcXVlc3Rpb25zIGlzIG11Y2ggbGFyZ2VyLiBUaGUgY29tcGxldCBpbnN0cnVtZW50IGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9uc3NlLmluZGlhbmEuZWR1L25zc2Uvc3VydmV5LWluc3RydW1lbnRzL3VzLWVuZ2xpc2guaHRtbD4uDQoNCjYuCSoqU2luZ2xlLWl0ZW0gcXVlc3Rpb25zKio6IFRoZXNlIHF1ZXN0aW9ucyBjYXB0dXJlIGRlbW9ncmFwaGljIGluZm9ybWF0aW9uLg0KDQoNCiMgUmF3IERhdGEgUHJvY2Vzc2luZw0KDQpBdCB0aGUgZW5kIG9mIGRhdGEgY29sbGVjdGlvbiwgd2UgcmVjZWl2ZWQgODk1IHJlc3BvbnNlcy4gT2YgdGhlc2UsIDE5OSBwYXJ0aWNpcGFudHMgZGlkIG5vdCBjb21wbGV0ZSB0aGUgbWFpbiBzdXJ2ZXkgc3Vic2NhbGVzLiBUaGUgYW5hbHlzaXMgaXMgYmFzZWQgb24gdGhlIHJlbWFpbmluZyA2OTYgcmVzcG9uc2VzIGZvciB3aGljaCB0aGUgbWFpbiBzdWJzY2FsZXMgd2VyZSBjb21wbGV0ZWQsIHdoaWNoIGNvbnRhaW5lZCBvbmx5IGEgZmV3IG1pc3NpbmcgdmFsdWVzLiBTZXZlcmFsIHJlZHVuZGFudCB2YXJpYWJsZXMgd2VyZSByZW1vdmVkIGZyb20gdGhlIHJhdyBkYXRhLiBJbiBhZGRpdGlvbiwgc29tZSBvcmlnaW5hbCBjYXRlZ29yaWNhbCB2YXJpYWJsZXMgd2VyZSByZWNhdGVnb3JpemVkIHRvIGF2b2lkIHNwYXJzZSBncm91cHMgYW5kIGltcHJvdmUgaW50ZXJwcmV0YWJpbGl0eS4NCg0KYGBge3IgZWNobyA9IEZBTFNFLCBldmFsID0gVFJVRX0NCldvcmtpbmdEYXRhIDwtIHJlYWQuY3N2KCJDOlxcVXNlcnNcXDc1Q1BFTkdcXE9uZURyaXZlIC0gV2VzdCBDaGVzdGVyIFVuaXZlcnNpdHkgb2YgUEFcXERlc2t0b3BcXGNwZW5nXFxXQ1UtVGVhY2hpbmdcXDIwMjVGYWxsXFxNYXRoQXhpZXR5XFxXb3JraW5nRGF0YVNldE5vTWlzc2luZ3MwMi5jc3YiKQ0KV29ya2luZ0RhdGEkSUQgPC0gMTpkaW0oV29ya2luZ0RhdGEpWzFdDQojIERlbW9ncmFwaGljcw0KRGVtb2dyYXBoaWNzIDwtIFdvcmtpbmdEYXRhWywgYygiSUQiLCAiU2V4IiwgIkdlbmRlciIsICJDbGFzcyIsICJNYWpvciIsICJFdGhuaWNpdHkiLCAiQ291cnNlMiIpXQ0KIyBNYXRoIEFueGlldHkNCkFueGlldHkgPC0gV29ya2luZ0RhdGFbLCBjKCJJRCIsICJBTUFTLjEiLCAiQU1BUy4yIiwgIkFNQVMuMyIsICJBTUFTLjQiLCAiQU1BUy41IiwgIkFNQVMuNiIsICJBTUFTLjciLCAiQU1BUy44IiwgIkFNQVMuOSIpXQ0KIyBTZWxmLWVmZmljYWN5DQpTZWxmRWZmaWNhY3kgPC0gV29ya2luZ0RhdGFbLCBjKCJJRCIsICAiTVNFUy4xIiwgIk1TRVMuMiIsICJNU0VTLjMiICldDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiMgICBUZWFjaGluZyBTdHJhdGVnaWVzDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiMjIENvb3BlcmF0aXZlDQpDb29wb3JhdGl2ZSA8LSBXb3JraW5nRGF0YVssIGMoIklEIiwgICJTLkNBLjEiLCAiUy5DQS4yIiwgIlMuQ0EuMyIsICJTLkNBLjQiLCAiUy5DQS41IiwgIlMuQ0EuNiIpXQ0KIyMgTGVjdHVyZSBUeXBlDQpMZWN0dXJlVHlwZSA8LSBXb3JraW5nRGF0YVssIGMoIklEIiwgICJTLkxULjEiLCAiUy5MVC4yIiwgIlMuTFQuMyIsICAiUy5MVC40IiwgICJTLkxULjUiLCAiUy5MVC42IiwgIlMuTFQuNyIpXQ0KIyMgRGVkdWN0aXZlIEFwcHJvYWNoDQpEZWR1Y3RpdmUgPC0gV29ya2luZ0RhdGFbLCBjKCJJRCIsICAiUy5EQS4xIiAsICJTLkRBLjIiLCAiUy5EQS4zIiwgIlMuREEuNCIsICJTLkRBLjUiLCAiUy5EQS42IiwgIlMuREEuNyIpXQ0KIyMgSW5kdWN0aXZlIEFwcHJvYWNoDQpJbmR1Y3RpdmUgPC0gV29ya2luZ0RhdGFbLCBjKCJJRCIsICJTLklBLjEiLCAiUy5JQS4yIiwgICJTLklBLjMiLCAgIlMuSUEuNCIsICJTLklBLjUiLCJTLklBLjYiLCAiUy5JQS43IildDQojIyBEZW1vbnN0cmF0aW9uDQpEZW1vbnN0cmF0aW9uIDwtV29ya2luZ0RhdGFbLCBjKCJJRCIsICJTLkQuMSIsICJTLkQuMiIsICJTLkQuMyIsICJTLkQuNCIsICJTLkQuNSIsICAiUy5ELjYiLCAiUy5ELjciKV0NCiMjIFJlcGV0aXRpdmUgRXhlcmNpc2VzDQpSZXBldGl0aXZlIDwtIFdvcmtpbmdEYXRhWywgYygiSUQiLCAiUy5SRS4xIiwgICJTLlJFLjIiLCAiUy5SRS4zIiwgIlMuUkUuNCIsICJTLlJFLjUiLCAiUy5SRS42IiwgIlMuUkUuNyIpXQ0KIyMgSW50ZWdyYXRpdmUgQXBwcm9hY2gNCkludGVncmF0aXZlIDwtIFdvcmtpbmdEYXRhWywgYygiSUQiLCAiUy5JQS4xLjEiLCAiUy5JQS4yLjEiLCAiUy5JQS4zLjEiLCAiUy5JQS40LjEiLCAiUy5JQS41LjEiLCAiUy5JQS42LjEiLCAiUy5JQS43LjEiKV0NCiMgVXNpbmcgVGVjaG5vbG9neTogZHJvcCBUMSBhbmQgVDcNClRlY2hub2xvZ3kgPC0gV29ya2luZ0RhdGFbLCBjKCJJRCIsICJULjIiLCAiVC4zIiwgIlQuNCIsICJULjUiLCAiVC42IiwgIlQuOCIsICJULjkiLCAiVC4xMCIsICJULjExIiwiVC4xMiIpXQ0KIyBMZWFybmluZyBNb2RhbGl0aWVzDQpNb2RhbGl0eSA8LSBXb3JraW5nRGF0YVssIGMoIklEIiwgICJNUy4xIiwgIk1TLjIiLCAiTVMuMyIsICJNUy40IiwgIk1TLjUiLCAiTVMuNiIsICJNUy43IiwgIk1TLjgiLCAiTVMuOSIsICJNUy4xMCIsICJNUy4xMSIsICJNUy4xMiIpXQ0KIyBFbmdhZ2VtZW50OiBrZWVwIG9ubHkgZmlyc3QgdGhyZWUgaXRlbXMNCkVuZ2FnZSA8LSBXb3JraW5nRGF0YVssIGMoIklEIiwgICJDUi4xIiwgIkNSLjIiLCAiQ1IuMyIpXQ0KIyBSZXNvdXJjZXMNClJlc291cmNlIDwtIFdvcmtpbmdEYXRhWywgYygiSUQiLCAiQ1IuOSIsICJDUi4xMCIsICJDUi4xMSIsICJDUi4xMiIpXQ0KYGBgDQoNCg0KDQojIyBNaXNzaW5nIFZhbHVlIEltcHV0YXRpb24NCg0KVG8gbWFpbiB0aGlzIHNhbXBsZSBzaXplLCB3ZSB1c2UgcmFuZG9tIGltcHV0YXRpb24gYXBwcm9hY2ggdG8gZmlsbCBpbiB0aGUgbWlzc2luZyB2YWx1ZXMuIFNpbmNlIGFsbCBtdWx0aS1pdGVtIHN1Yi1zY2FsZXMgd2VyZSBtZWFzdXJlZCB1c2luZyBhIExpa2VydCBzY2FsZSwgdGhlIHNjb3JlcyBmb2xsb3dzIGEgbXVsdGlub21pYWwgZGlzdHJpYnV0aW9uLiBUaGUgZW1waXJpY2FsIGRpc3RyaWJ1dGlvbiB3aWxsIGJlIHVzZWQgaW4gdGhlIHJhbmRvbSBpbXB1dGF0aW9uIHRvIG1haW4gdGhlIHByb2JhYmlsaXR5IGRpc3RyaWJ1dGlvbiBvZiB0aGUgb2JzZXJ2ZWQgZGF0YS4gVGhlIGZvbGxvd2luZyBjb2RlIGltcHV0ZXMgdGhlIG1pc3NpbmcgdmFsdWVzIGluIGFsbCBtdWx0aS1pdGVtIHN1YnNjYWxlcy4NCg0KYGBge3IsIGV2YWwgPSBUUlVFfQ0KSW1wdXRhdGlvbiA9IGZ1bmN0aW9uKERhdGFOYW1lKXsNCiAgZm9yIChpIGluIDE6KGRpbShEYXRhTmFtZSlbMl0pKXsNCiAgICB2ZWMgPSBhcy52ZWN0b3IoRGF0YU5hbWVbLCBpXSkNCiAgICBuYS5pZCA9IHdoaWNoKGlzLm5hKHZlYykpDQogICAgbjAgPSBsZW5ndGgobmEuaWQpDQogICAgcHJvYjAgPSB0YWJsZSh2ZWMpL2xlbmd0aCh2ZWMpDQogICAgaW1wdXQudmFsID0gTlVMTA0KICAgICAgZm9yIChqIGluIDE6bjApew0KICAgICAgaW1wdXQudmFsW2pdID0gc2FtcGxlKDE6bGVuZ3RoKHByb2IwKSwgc2l6ZSA9IDEsIHByb2IgPSBwcm9iMCkNCiAgICB9DQogICAgRGF0YU5hbWVbbmEuaWQsIGldID0gaW1wdXQudmFsDQogIH0NCiAgIERhdGFOYW1lDQp9DQpgYGANCg0KDQpgYGB7ciBlY2hvID0gRkFMU0UsIGV2YWwgPSBUUlVFfQ0KQ29tcC5BbnhpZXR5ID0gSW1wdXRhdGlvbihBbnhpZXR5KQ0KQ29tcC5TZWxmRWZmaWNhY3kwID0gSW1wdXRhdGlvbihTZWxmRWZmaWNhY3kpDQojIHJldmVyc2UgY29kaW5nIGluIFNlbGYtRWZmaWNhY3kNCkNvbXAuU2VsZkVmZmljYWN5ID0gQ29tcC5TZWxmRWZmaWNhY3kwDQpDb21wLlNlbGZFZmZpY2FjeSRNU0VTLjEgPTYtIENvbXAuU2VsZkVmZmljYWN5MCRNU0VTLjENCkNvbXAuU2VsZkVmZmljYWN5JE1TRVMuMyA9Ni0gQ29tcC5TZWxmRWZmaWNhY3kwJE1TRVMuMw0KIyMNCkNvbXAuQ29vcG9yYXRpdmUgPSBJbXB1dGF0aW9uKENvb3BvcmF0aXZlKQ0KQ29tcC5MZWN0dXJlVHlwZSA9IEltcHV0YXRpb24oTGVjdHVyZVR5cGUpDQpDb21wLkRlZHVjdGl2ZSA9IEltcHV0YXRpb24oRGVkdWN0aXZlKQ0KQ29tcC5JbmR1Y3RpdmUgPSBJbXB1dGF0aW9uKEluZHVjdGl2ZSkNCkNvbXAuRGVtb25zdHJhdGlvbiA9IEltcHV0YXRpb24oRGVtb25zdHJhdGlvbikNCkNvbXAuUmVwZXRpdGl2ZSA9IEltcHV0YXRpb24oUmVwZXRpdGl2ZSkNCkNvbXAuSW50ZWdyYXRpdmUgPSBJbXB1dGF0aW9uKEludGVncmF0aXZlKQ0KIyMgcmV2ZXJzZSBjb2RpbmcgaW4gNSBhbmQgNyBpbiBUZWNobm9sb2d5DQpDb21wLlRlY2hub2xvZ3kwID0gSW1wdXRhdGlvbihUZWNobm9sb2d5KQ0KQ29tcC5UZWNobm9sb2d5MSA9IENvbXAuVGVjaG5vbG9neTANCkNvbXAuVGVjaG5vbG9neTEkVC41ID02LSBDb21wLlRlY2hub2xvZ3kwJFQuNQ0KIyMNCkNvbXAuVGVjaG5vbG9neSA9IDYgLSBDb21wLlRlY2hub2xvZ3kxDQojIw0KQ29tcC5FbmdhZ2UgPSA1LUltcHV0YXRpb24oRW5nYWdlKQ0KQ29tcC5SZXNvdXJjZSA9IDUtSW1wdXRhdGlvbihSZXNvdXJjZSkNCiMjIE1vZGFsaXR5DQpDb21wLk1vZGFsaXR5ID0gSW1wdXRhdGlvbihNb2RhbGl0eSkNCmBgYA0KDQoNCiMjIFJldmVyc2UgU2NvcmluZw0KDQoqKlJldmVyc2Ugc2NvcmluZyoqIGlzIGEgY3J1Y2lhbCBkYXRhIHByZXBhcmF0aW9uIHN0ZXAgZm9yIG11bHRpLWl0ZW0gc3VydmV5cyB3aGVyZSBzb21lIGl0ZW1zIGFyZSB3b3JkZWQgaW4gdGhlIG9wcG9zaXRlIGRpcmVjdGlvbiB0byBwcmV2ZW50IHJlc3BvbnNlIGJpYXMuIEFmdGVyIGl0ZW0td2lzZSByZXZpZXcgb2YgYWxsIGluc3RydW1lbnRzIGFsb25nIHdpdGggc3RhdGlzdGljYWwgcHJvY2VkdXJlcyBvZiBjb3JyZWxhdGlvbiBhbmQgY29uZmlybWF0b3J5IGZhY3RvciBhbmFseXNpcyAoQ0ZBKSwgaXRlbSAyIGluIHRoZSAqU2VsZi1lZmZpY2FjeSBJbnN0cnVtZW50KiBhbmQgKiphbGwgcXVlc3Rpb25zKiogZXhjZXB0IGl0ZW1zIDUgYW5kIDcgaW4gdGhlICpUZWNobm9sb2d5IEluc3RydW1lbnQqIHdlcmUgbmVnYXRpdmVseSB3b3JkZWQuIFRoZSBzY29yZXMgb2YgdGhlc2UgaXRlbXMgd2VyZSByZXZlcnNlZC4NCg0KSW4gYWRkaXRpb24sIGFsbCBxdWVzdGlvbnMgcmVnYXJkaW5nIGVuZ2FnZW1lbnQgYW5kIHJlc291cmNlIHVzZSB3ZXJlIHJldmVyc2Utd29yZGVkLCBzbyB0aGVpciBzY29yZXMgd2VyZSByZXZlcnNlZCBmb3IgdGhlIHN1YnNlcXVlbnQgYW5hbHlzaXMuDQoNCg0KIyMgU3BhcnNlIENhdGVnb3J5IFJlZ3JvdXBpbmcNCg0KVHdvIHZhcmlhYmxlcyBuZWVkIHRvIGJlIHJlZ3JvdXBlZCBpbiB0aGUgZm9sbG93aW5nOiBjb3Vyc2UgbGV2ZWwgYW5kIGV0aG5pY2l0eS4NCg0KKiAqKk1hdGhDb3Vyc2VMZXZlbCoqDQogICsgKk1hdGguSSo6IE1BVFEzMCwgTUFUMTAwLCBNQVQxMDEsIE1BVDEwMiwNCiAgKyAqTWF0aC5JSSo6IE1BVDE5MywgTUFUMTA0LCBNQVQxMTIsIE1BVDExMywgTUFUMTE1LCBNQVQxMzENCiAgKyAqTWF0aC5JSUkqOiBNQVQxNDMsIE1BVDE0NSwgTUFUMTUxLCBNQVQxNjENCiAgKyAqTWF0aC5JVio6IE1BVDE2Mi1NQVQ0ODANCiAgKyAqU3RhdHMqOiBNQVQxMjEsIE1BVDEyNSwgU1RBMjAwDQogICsgKk90aGVyKjogQWxsIGNvdXJzZXMgbm90IGxpc3RlZCBhYm92ZQ0KDQoqICoqRXRobmljaXR5KioNCiAgKyAqV2hpdGUqDQogICsgKkJsYWNrKjogQmxhY2sgYW5kIEFmcmljYW4gQW1lcmljYW4NCiAgKyAqQXNpYW4qDQogICsgKk90aGVyKjogTmF0aXZlIEhhd2FpaWFuIG9yIFBhY2lmaWMgSXNsYW5kZXIsIE11bHRpcGxlIEV0aG5pY2l0eSBvciBPdGhlciwgUHJlZmVyIE5vdCBUbyBBbnN3ZXINCg0KKiAqKkxlYXJuaW5nIE1vZGFsaXRpZXMqKg0KDQpgYGB7cn0NCmRmX3dpdGhfZnJlcSA8LSBDb21wLk1vZGFsaXR5ICU+JQ0KICByb3d3aXNlKCkgJT4lDQogIG11dGF0ZSgNCiAgICBmcmVxX0EgPSBzdW0oY19hY3Jvc3MoTVMuMTpNUy4xMikgPT0gIjEiKSwNCiAgICBmcmVxX0IgPSBzdW0oY19hY3Jvc3MoTVMuMTpNUy4xMikgPT0gIjIiKSwNCiAgICBmcmVxX0MgPSBzdW0oY19hY3Jvc3MoTVMuMTpNUy4xMikgPT0gIjMiKQ0KICApICU+JQ0KICB1bmdyb3VwKCkNCiMjIw0KZGZfd2l0aF9mcmVxJG1heF9mcmVxX2NvbCA8LSBuYW1lcyhkZl93aXRoX2ZyZXEpW21heC5jb2woZGZfd2l0aF9mcmVxWywgYygiZnJlcV9BIiwgImZyZXFfQiIsICJmcmVxX0MiKV0pICsgMV0NCmRmX3dpdGhfZnJlcSRtYXhfZnJlcV92YWx1ZSA8LSBhcHBseShkZl93aXRoX2ZyZXFbLCBjKCJmcmVxX0EiLCAiZnJlcV9CIiwgImZyZXFfQyIpXSwgMSwgbWF4KQ0KZGZfd2l0aF9mcmVxJG1vZGFsaXR5IDwtIGlmZWxzZShkZl93aXRoX2ZyZXEkbWF4X2ZyZXFfY29sPT0iTVMuMSIsICJBdWRpdG9yeSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoZGZfd2l0aF9mcmVxJG1heF9mcmVxX2NvbD09Ik1TLjIiLCAiVmlzdWFsIiwgIktpbmVzdGhldGljIikpDQoNCmBgYA0KDQoNCg0KDQpgYGB7ciwgZWNobyA9IEZBTFNFLCBldmFsID0gVFJVRX0NCkRlbW9ncmFwaGljcyRtYXRoLmxldmVsID0gaWZlbHNlKERlbW9ncmFwaGljcyRDb3Vyc2UyICVpbiUgYygxLCAyLCAzLCA0KSwgIm1hdGgwMSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKERlbW9ncmFwaGljcyRDb3Vyc2UyICVpbiUgYyg1LCA2LCA3LCA4LCA5LCAxMiksICJtYXRoMDIiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoRGVtb2dyYXBoaWNzJENvdXJzZTIgJWluJSBjKDEzLCAxNCwgMTUsIDE2KSwgIm1hdGgwMyIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoRGVtb2dyYXBoaWNzJENvdXJzZTIgJWluJSBjKDEwLCAxMSwgMzYsIDM3LCAzOCwgMzksIDQwLCA0MSwgNDIpLCAic3RhdHMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKERlbW9ncmFwaGljcyRDb3Vyc2UyICVpbiUgYyg0MywgNDQpLCAib3RoZXIiLCAibWF0aDA0IikpKSkpIA0KRGVtb2dyYXBoaWNzJHJhY2UgPSBpZmVsc2UoRGVtb2dyYXBoaWNzJEV0aG5pY2l0eSA9PSAxLCAid2hpdGUiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShEZW1vZ3JhcGhpY3MkRXRobmljaXR5ID09IDIsICJCbGFjayIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShEZW1vZ3JhcGhpY3MkRXRobmljaXR5ID09IDQsICJBc2lhbiIsICJvdGhlciIpKSkNCkRlbW9ncmFwaGljcyRzZXggPSBpZmVsc2UoRGVtb2dyYXBoaWNzJFNleCA9PSAxLCAiZmVtYWxlIiwgIm1hbGUiKQ0KRGVtb2dyYXBoaWNzJG1ham9yID0gaWZlbHNlKERlbW9ncmFwaGljcyRNYWpvciA9PSAxLCAiU1RFTSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShEZW1vZ3JhcGhpY3MkTWFqb3IgPT0gMiwgIkJ1c2luZXNzIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKERlbW9ncmFwaGljcyRNYWpvciA9PSAzLCAiSGVhbHRoIiwgIk90aGVyIikpKQ0KRGVtb2dyYXBoaWNzJGNsYXNzID0gaWZlbHNlKERlbW9ncmFwaGljcyRDbGFzcyA9PSAxLCAieXIxIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKERlbW9ncmFwaGljcyRDbGFzcyA9PSAyLCAieXIyIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKERlbW9ncmFwaGljcyRDbGFzcyA9PSAzLCAieXIzIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoRGVtb2dyYXBoaWNzJE1ham9yID09IDQsICJ5cjQiLCAieXI1KyIpKSkpDQpEZW1vZ3JhcGhpY3MkbW9kYWxpdHkgPC0gZGZfd2l0aF9mcmVxJG1vZGFsaXR5DQoNCmRlbW9ncmFwaGljcyA9IERlbW9ncmFwaGljc1ssIGMoIklEIiwgInNleCIsICJyYWNlIiwgImNsYXNzIiwgIm1ham9yIiwgIm1hdGgubGV2ZWwiLCAibW9kYWxpdHkiKV0NCmBgYA0KDQoNCiMjIEV4cGxvcmF0b3J5IEZhY3RvciBBbmFseXNpcyAoRUZBKSBvbiBBbnhpZXR5DQoNClRoZSBhYmJyZXZpYXRlZCBtYXRoZW1hdGljYWwgYW54aWV0eSAoTUEpIGluc3RydW1lbnQgZGV2ZWxvcGVkIGJ5IEhvcGtvIGV0IGFsLiAoMjAwMykgaXMgY2hhcmFjdGVyaXplZCBieSBhIHR3by1mYWN0b3Igc3RydWN0dXJlIHRoYXQgZGl2aWRlcyBpbnRvIHR3byBzdWJzY2FsZXM6IG1hdGhlbWF0aWNzIGV2YWx1YXRpb24gYW54aWV0eSAoTUVBKSBhbmQgbWF0aGVtYXRpY3MgbGVhcm5pbmcgYW54aWV0eSAoTUxBKS4gVGhlIHN1YnNlcXVlbnQgZXhwbG9yYXRvcnkgZmFjdG9yIGFuYWx5c2lzIHNlcnZlcyB0byB2YWxpZGF0ZSB0aGlzIGNvbnN0cnVjdC4NCg0KDQpgYGB7ciByZXN1bHRzID0gRkFMU0V9DQojIENoZWNrIGNvcnJlbGF0aW9ucyAodmlzdWFsbHkpDQpuID0gZGltKENvbXAuQW54aWV0eVssLTFdKVsxXQ0KY29yX21hdHJpeCA8LSBjb3IoQ29tcC5BbnhpZXR5WywtMV0pDQojY29yUGxvdChjb3JfbWF0cml4LCB1cHBlciA9IEZBTFNFKQ0KIyBCYXJ0bGV0dCdzIFRlc3Qgb2YgU3BoZXJpY2l0eSAod2Ugd2FudCBhIHNpZ25pZmljYW50IHAtdmFsdWUsIHAgPCAuMDUpDQpjb3J0ZXN0LmJhcnRsZXR0KGNvcl9tYXRyaXgsIG4gPSBuKQ0KDQojIEtNTyBNZWFzdXJlIG9mIFNhbXBsaW5nIEFkZXF1YWN5IChNU0EpIChXZSB3YW50IG92ZXJhbGwgTVNBID4gMC42LCBpZGVhbGx5ID4gMC44KQ0KS01PKGNvcl9tYXRyaXgpDQpgYGANCg0KQmFydGxldHQncyB0ZXN0IG9mIHNwaGVyaWNpdHkgcHJvZHVjZWQgYSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IHJlc3VsdCAocCA8IC4wMDEpLCBjb25maXJtaW5nIHRoYXQgdGhlIHZhcmlhYmxlcyBhcmUgc3VmZmljaWVudGx5IGNvcnJlbGF0ZWQgdG8gcHJvY2VlZCB3aXRoIGZhY3RvciBhbmFseXNpcy4gVGhlIEthaXNlci1NZXllci1PbGtpbiAoS01PKSBNZWFzdXJlIG9mIFNhbXBsaW5nIEFkZXF1YWN5LCB3aXRoIGJvdGggb3ZlcmFsbCBhbmQgaXRlbS1sZXZlbCB2YWx1ZXMgZXhjZWVkaW5nIDAuODAsIGluZGljYXRlcyB0aGF0IHRoZSBkYXRhIGNvbnRhaW4gYWRlcXVhdGUgY29tbW9uIHZhcmlhbmNlIHRvIHdhcnJhbnQgZmFjdG9yIGFuYWx5c2lzLiBGdXJ0aGVybW9yZSwgdGhlIHNjcmVlIHBsb3QgY2xlYXJseSBkZW1vbnN0cmF0ZXMgdGhlIGFudGljaXBhdGVkIHR3by1mYWN0b3Igc3RydWN0dXJlIG9mIHRoZSBjb25zdHJ1Y3QuDQoNCg0KYGBge3J9DQoNCiMgR2V0IGVpZ2VudmFsdWVzDQpmYV9yZXN1bHQgPC0gZmEoQ29tcC5BbnhpZXR5WywtMV0sIG5mYWN0b3JzID0gbmNvbChDb21wLkFueGlldHlbLC0xXSksIHJvdGF0ZSA9ICJub25lIikNCmVpZ2VudmFsdWVzIDwtIGZhX3Jlc3VsdCRlLnZhbHVlcw0KDQojIFNjcmVlIHBsb3Qgd2l0aCBob3Jpem9udGFsIGxpbmUgdXNpbmcgc2hhcGVzDQpzY3JlZV9wbG90IDwtIHBsb3RfbHkoeCA9IDE6bGVuZ3RoKGVpZ2VudmFsdWVzKSwgeSA9IGVpZ2VudmFsdWVzLA0KICAgICAgICAgICAgICAgICAgICAgIHR5cGUgPSAnc2NhdHRlcicsIG1vZGUgPSAnbGluZXMrbWFya2VycycsDQogICAgICAgICAgICAgICAgICAgICAgbGluZSA9IGxpc3Qod2lkdGggPSAzKSwNCiAgICAgICAgICAgICAgICAgICAgICBtYXJrZXIgPSBsaXN0KHNpemUgPSA4KSkgJT4lDQogIGxheW91dCgNCiAgICB0aXRsZSA9ICJTY3JlZSBQbG90IHdpdGggS2Fpc2VyIENyaXRlcmlvbiAoRWlnZW52YWx1ZSkiLA0KICAgIHhheGlzID0gbGlzdCh0aXRsZSA9ICJGYWN0b3IgTnVtYmVyIiksDQogICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIkVpZ2VudmFsdWUiKSwNCiAgICBzaGFwZXMgPSBsaXN0KA0KICAgICAgbGlzdCgNCiAgICAgICAgdHlwZSA9ICJsaW5lIiwNCiAgICAgICAgeDAgPSAwLA0KICAgICAgICB4MSA9IGxlbmd0aChlaWdlbnZhbHVlcyksDQogICAgICAgIHkwID0gMSwNCiAgICAgICAgeTEgPSAxLA0KICAgICAgICBsaW5lID0gbGlzdChjb2xvciA9ICJyZWQiLCB3aWR0aCA9IDIsIGRhc2ggPSAiZGFzaCIpDQogICAgICApDQogICAgKSwNCiAgICBhbm5vdGF0aW9ucyA9IGxpc3QoDQogICAgICBsaXN0KA0KICAgICAgICB4ID0gbGVuZ3RoKGVpZ2VudmFsdWVzKSAqIDAuOCwNCiAgICAgICAgeSA9IDEuMSwNCiAgICAgICAgdGV4dCA9ICJLYWlzZXIgQ3JpdGVyaW9uICjOuyA9IDEpIiwNCiAgICAgICAgc2hvd2Fycm93ID0gRkFMU0UsDQogICAgICAgIGZvbnQgPSBsaXN0KGNvbG9yID0gInJlZCIpDQogICAgICApDQogICAgKSwNCiAgICAgbWFyZ2luID0gbGlzdCgNCiAgICAgICAgICAgICAgICAgIHQgPSAxMDAsICAjIEFkanVzdCB0aGlzIHZhbHVlIHRvIGluY3JlYXNlIG9yIGRlY3JlYXNlIHRoZSB0b3AgbWFyZ2luDQogICAgICAgICAgICAgICAgICBiID0gNTAsDQogICAgICAgICAgICAgICAgICBsID0gNTAsDQogICAgICAgICAgICAgICAgICByID0gNTApDQogICkNCg0Kc2NyZWVfcGxvdA0KYGBgDQoNCk5leHQsIHdlIHBlcmZvcm0gRUZBIHRvIGlkZW50aWZ5IHRoZSBpdGVtcyBvZiBNRUEgYW5kIE1MQSB0aHJvdWdoIGZhY3RvciBsb2FkaW5ncy4gDQoNCmBgYHtyfQ0KIyMgdHdvLWZhY3RvciBhRUZBDQplZmFfMmZhY3RvciA8LSBmYShDb21wLkFueGlldHlbLC0xXSwgbmZhY3RvcnMgPSAyLCByb3RhdGUgPSAib2JsaW1pbiIsIA0KICAgICAgICAgICAgICAgICAgZm0gPSAicGEiLCBzY29yZXMgPSAicmVncmVzc2lvbiIpDQojIENyZWF0ZSBhIGNsZWFuIGxvYWRpbmdzIHRhYmxlDQpsb2FkaW5nc190YWJsZSA8LSBmYS5zb3J0KGVmYV8yZmFjdG9yJGxvYWRpbmdzW10pDQpwYW5kZXIobG9hZGluZ3NfdGFibGUsIGRpZ2l0cyA9IDIsIGN1dG9mZiA9IDAuMykNCmBgYA0KDQpBcyBzaG93biBpbiB0aGUgdGFibGUgYWJvdmUsIGl0ZW1zIDIsIDQsIDUsIGFuZCA4IGxvYWQgb250byB0aGUgZXZhbHVhdGlvbiBhbnhpZXR5IGZhY3Rvciwgd2hlcmVhcyB0aGUgcmVtYWluaW5nIGl0ZW1zIGxvYWQgb250byB0aGUgbGVhcm5pbmcgYW54aWV0eSBmYWN0b3IuIFR3byBkaXN0aW5jdCBzdWJzY2FsZXMgd2lsbCBiZSBlc3RhYmxpc2hlZCBmb3Igc3Vic2VxdWVudCBhbmFseXNlcy4NCg0KYGBge3J9DQpBbnhpZXR5Lm1lYSA8LSBDb21wLkFueGlldHlbLCBjKCJJRCIsICAiQU1BUy4yIiwgIkFNQVMuNCIsICJBTUFTLjUiLCAgIkFNQVMuOCIpXQ0KQW54aWV0eS5tbGEgPC0gQ29tcC5BbnhpZXR5WywgYygiSUQiLCAiQU1BUy4xIiwgIkFNQVMuMyIsICJBTUFTLjYiLCAiQU1BUy43IiwgIkFNQVMuOSIpXQ0KYGBgDQoNCg0KIyBWYWxpZGF0aW9uIGFuZCBSZWxpYWJpbGl0eQ0KDQpUaGUgbWFqb3IgbXVsdGktaXRlbSBpbnN0cnVtZW50cyB1c2VkIGluIHRoaXMgc3R1ZHkgYXJlIHdlbGwtZXN0YWJsaXNoZWQgYW5kIGhhdmUgYmVlbiB1c2VkIGluIHZhcmlvdXMgcHVibGlzaGVkIHJlc2VhcmNoLiBJbiBwcmFjdGljZSwgdGhlIHZhbGlkaXR5IGFuZCByZWxpYWJpbGl0eSBvZiBzdWNoIGVzdGFibGlzaGVkIGluc3RydW1lbnRzIG11c3QgYmUgY29uZmlybWVkIGJlZm9yZSBhbnkgc3RhdGlzdGljYWwgYW5hbHlzaXMuIFdlIG5leHQgcGVyZm9ybSByZWxpYWJpbGl0eSBhbmQgdmFsaWRpdHkgYW5hbHlzZXMgdG8gd2FycmFudCB0aGUgY3JlZGliaWxpdHkgb2YgdGhlIG92ZXJhbGwgc3VydmV5IGRlc2lnbiBhbmQgdGhlIHF1YWxpdHkgb2YgdGhlIGNvbGxlY3RlZCBkYXRhLg0KDQoNCiMjIFZhbGlkaXR5IEFuYWx5c2lzDQoNCioqVmFsaWRpdHkqKiBvZiBhIG11bHRpLWl0ZW0gc3VydmV5IGluc3RydW1lbnQgYW5zd2VycyB0aGUgcXVlc3Rpb246ICJBbSBJIGFjdHVhbGx5IG1lYXN1cmluZyB3aGF0IEkgaW50ZW5kIHRvIG1lYXN1cmU/IiBJdCdzIGFib3V0IHRoZSBzb3VuZG5lc3Mgb2YgdGhlIGludGVycHJldGF0aW9uIG9mIHRoZSBzY29yZXMuIEluIHBzeWNob21ldHJpY3MsICoqdmFsaWRpdHkqKiByZWZlcnMgdG8gdGhlIGRlZ3JlZSB0byB3aGljaCBhIHNjYWxlIG1lYXN1cmVzIHdoYXQgaXQgY2xhaW1zIHRvIG1lYXN1cmUuIEZvciBhIHNpbmdsZS1mYWN0b3IgaW5zdHJ1bWVudCwgdGhpcyBtZWFucyBhbGwgaXRlbXMgYXJlIGluZGljYXRvcnMgb2Ygb25lIHVuZGVybHlpbmcgY29uc3RydWN0IHN1Y2ggYXMgbWF0aHMgYW54aWV0eSwgc2VsZi1lZmZpY2FjeSwgZW5nYWdlbWVudCwgZXRjLiBpbiB0aGlzIGNvbXByZWhlbnNpdmUgc3VydmV5LiBUaGUgQ0ZBIGhhcyBiZWVuIHVzZWQgaW4gc3VydmV5IHJlc2VhcmNoIHdpZGVseSwgc2VlIFdhdHNvbiwgZXQgYWwgKDE5ODgpIGFuZCBNYXJzaCAoMTk5NikuIA0KDQoqKkNvbmZpcm1hdG9yeSBGYWN0b3IgQW5hbHlzaXMgKENGQSkqKiBpcyBhIHBvd2VyZnVsIHN0YXRpc3RpY2FsIHRlY2huaXF1ZSB1c2VkIHRvIHRlc3QgYSBwcmUtc3BlY2lmaWVkIHRoZW9yeSBhYm91dCB0aGUgc3RydWN0dXJlIG9mIHlvdXIgaW5zdHJ1bWVudC4gV2UgdXNlIENGQSB0byBjb25maXJtIHRoYXQgeW91ciBoeXBvdGhlc2l6ZWQgc2luZ2xlLWZhY3RvciBtb2RlbCBpcyBjb25zaXN0ZW50IHdpdGggdGhlIG9ic2VydmVkIGRhdGEuIEl0IHByb3ZpZGVzIHJpZ29yb3VzIGV2aWRlbmNlIGZvciBjb25zdHJ1Y3QgdmFsaWRpdHkgaW4gYSBsaXN0IG9mIGNvbnZlbnRpb25hbCBtZWFzdXJlczoNCg0KKiAqKkZhY3RvciBMb2FkaW5ncyoqIGFyZSB0aGUgc3RhbmRhcmRpemVkIHdlaWdodHMgZnJvbSB0aGUgQ29uZmlybWF0b3J5IEZhY3RvciBBbmFseXNpcyAoQ0ZBKS4gVGhlIHN1Z2dlc3RlZCBndWlkZWxpbmVzIGFyZToNCiAgKyBBIGxvYWRpbmcgKiptYWduaXR1ZGUgZ3JlYXRlciB0aGFuIDAuNSoqIGluZGljYXRlcyB0aGF0IHRoZSBpdGVtIHNoYXJlcyBhdCBsZWFzdCAyNSUgb2YgaXRzIHZhcmlhbmNlIHdpdGggdGhlIGxhdGVudCBmYWN0b3IuIEluIHRoZSBmb2xsb3dpbmcgdGFibGUsIHdlIHJlcG9ydCB0aGUgbWluaW11bSBsb2FkaW5nIGZvciBlYWNoIGluc3RydW1lbnQgdW5kZXIgdGhlIGNvbHVtbiBgc3RkLmFsbC5taW5gLg0KICArIEFsbCBsb2FkaW5ncyBtdXN0IGJlIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgKHAgPCAwLjA1KS4gV2UgcmVwb3J0IHRoZSBtYXhpbXVtIHAtdmFsdWUgZm9yIGVhY2ggaW5zdHJ1bWVudCB1bmRlciB0aGUgY29sdW1uIGBwdmFsLm1heGAuDQoNCiogKipTdGFuZGFyZGl6ZWQgUm9vdCBNZWFuIFNxdWFyZSBSZXNpZHVhbCAoU1JNUikqKiBtZWFzdXJlcyB0aGUgZ29vZG5lc3Mtb2YtZml0IG9mIHRoZSBDRkEgbW9kZWwuIEl0IHJlcHJlc2VudHMgdGhlIGF2ZXJhZ2Ugc3RhbmRhcmRpemVkIHJlc2lkdWFsIGJldHdlZW4gdGhlIG9ic2VydmVkIGFuZCBwcmVkaWN0ZWQgY29ycmVsYXRpb24gbWF0cmljZXMuIEEgbG93ZXIgdmFsdWUgaW5kaWNhdGVzIGEgYmV0dGVyIGZpdCwgd2l0aCBhIHN1Z2dlc3RlZCBjdXRvZmYgb2YgKipsZXNzIHRoYW4gMC4wOCoqLg0KDQoqICoqQ29tcGFyYXRpdmUgRml0IEluZGV4IChDRkkpKiogaXMgYW5vdGhlciBnb29kbmVzcy1vZi1maXQgbWVhc3VyZSBmb3IgdGhlIENGQS4gSXQgY29tcGFyZXMgdGhlIHNwZWNpZmllZCBtb2RlbCB0byBhIG51bGwgKGluZGVwZW5kZW5jZSkgbW9kZWwuIEEgaGlnaGVyIHZhbHVlIGluZGljYXRlcyBhIGJldHRlciBmaXQsIHdpdGggYSBzdWdnZXN0ZWQgY3V0b2ZmIG9mICoqZ3JlYXRlciB0aGFuIDAuOSoqLg0KDQoqICoqVHVja2VyLUxld2lzIEluZGV4IChUTEkpKiogYWxzbyBtZWFzdXJlcyB0aGUgZ29vZG5lc3Mtb2YtZml0IG9mIHRoZSBDRkEuIEl0cyBpbnRlcnByZXRhdGlvbiBhbmQgdXNhZ2UgYXJlIHNpbWlsYXIgdG8gdGhvc2Ugb2YgdGhlIENGSS4NCg0KQWZ0ZXIgc29tZSBleHBsb3JhdG9yeSBhbmFseXNpcywgd2UgZHJvcHBlZCBhIGZldyBpdGVtcyBmcm9tIHRoZSBUZWNobm9sb2d5IEluc3RydW1lbnQgYW5kIGRlZmluZWQgdHdvIHN1Y3NjYWxlcyBvZiB0aGUgaW5pdGlhbCByZXNvdXJjZSBpbnN0cnVtZW50czogKip1c2Ugb2YgcmVzb3VyY2UqKiBhbmQgKipzdHVkZW50IGVuZ2FnZW1lbnQqKi4NCg0KDQpUaGUgZmluYWwgcmVzdWx0cyBvbiB0aGUgc3RydWN0IHZhbGlkaXR5IG1lYXN1cmVzIGFyZSBzdW1tYXJpemVkIGluIHRoZSBmb2xsb3dpbmcgdGFibGUuDQoNCmBgYHtyIGVjaG8gPSBUUlVFLCBldmFsID0gVFJVRX0NCmNmYS5hbmFseXNpcyA8LSBmdW5jdGlvbihkYXRhc2V0KXsNCiAgI2RhdGFzZXQgPC0gQ29tcC5BbnhpZXR5DQogIHByZWRpY3RvcnMgPC0gbmFtZXMoZGF0YXNldFssIC0xXSkgIA0KICBuMCA8LSBsZW5ndGgocHJlZGljdG9ycykNCiAgY2ZhLm1vZGVsIDwtICBwYXN0ZSgibGF0ZW50ID1+IiwgcGFzdGUocHJlZGljdG9ycywgY29sbGFwc2UgPSAiICsgIikpDQogIGNmYS5maXQgPC0gY2ZhKGNmYS5tb2RlbCwgZGF0YSA9IGRhdGFzZXRbLCAtMV0sIGVzdGltYXRvciA9ICJNTE0iKQ0KICByZXN1bHRzIDwtIHN1bW1hcnkoY2ZhLmZpdCwgc3RhbmRhcmRpemVkID0gVFJVRSwgZml0Lm1lYXN1cmVzID0gVFJVRSwgcnNxdWFyZSA9IFRSVUUpDQogIHN0ZC5hbGwubWluIDwtIG1pbihyZXN1bHRzJHBlJHN0ZC5sdlsxOm4wXSkNCiAgcHZhbC5tYXggPC0gbWF4KHJlc3VsdHMkcGUkcHZhbHVlWzI6bjBdKQ0KICBzcm1yIDwtIHJlc3VsdHMkZml0WyJzcm1yIl0NCiAgY2ZpIDwtIHJlc3VsdHMkZml0WyJjZmkiXQ0KICB0bGkgPC0gcmVzdWx0cyRmaXRbInRsaSJdDQogICNybXNlYSA8LSByZXN1bHRzJGZpdFsicm1zZWEiXQ0KICBjYmluZChzdGQuYWxsLm1pbiA9IHN0ZC5hbGwubWluLCBwdmFsLm1heCA9IHB2YWwubWF4LCBzcm1yID0gc3JtciwgY2ZpID0gY2ZpLCAgdGxpID0gdGxpKQ0KfQ0KYGBgDQoNCg0KYGBge3IgZWNobyA9IFRSVUUsIGV2YWwgPSBUUlVFLCBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmc9RkFMU0V9DQphbnhpZXR5Lm1lYS52bGlkIDwtY2ZhLmFuYWx5c2lzKEFueGlldHkubWVhKQ0KYW54aWV0eS5tbGEudmxpZCA8LWNmYS5hbmFseXNpcyhBbnhpZXR5Lm1sYSkNCmFueGlldHkudmxpZCA8LWNmYS5hbmFseXNpcyhDb21wLkFueGlldHkpDQplZmZpY2FjeS52bGlkIDwtY2ZhLmFuYWx5c2lzKENvbXAuU2VsZkVmZmljYWN5KQ0KdGVjaC52bGlkIDwtY2ZhLmFuYWx5c2lzKENvbXAuVGVjaG5vbG9neSkNCmNvb3BlcmF0aXZlLnZsaWQgPC1jZmEuYW5hbHlzaXMoQ29tcC5Db29wb3JhdGl2ZSkNCmRlZHVjdGl2ZS52bGlkIDwtY2ZhLmFuYWx5c2lzKENvbXAuRGVkdWN0aXZlKQ0KZGVtby52bGlkIDwtY2ZhLmFuYWx5c2lzKENvbXAuRGVtb25zdHJhdGlvbikNCmluZHVjdGl2ZS52bGlkIDwtY2ZhLmFuYWx5c2lzKENvbXAuSW5kdWN0aXZlKQ0KaW50ZWdyYXRlLnZsaWQgPC1jZmEuYW5hbHlzaXMoQ29tcC5JbnRlZ3JhdGl2ZSkNCmxlY3R1cmUudmxpZCA8LWNmYS5hbmFseXNpcyhDb21wLkxlY3R1cmVUeXBlKQ0KcmVwZXRpdmUudmxpZCA8LWNmYS5hbmFseXNpcyhDb21wLlJlcGV0aXRpdmUpDQplbmdhZ2UudmxpZCA8LWNmYS5hbmFseXNpcyhDb21wLkVuZ2FnZSkNCnJlc291cmNlLnZsaWQgPC1jZmEuYW5hbHlzaXMoQ29tcC5SZXNvdXJjZSkNCiMjDQp2bGlkLnRhYmxlIDwtcmJpbmQoYW54aWV0eS5tZWEgPSBhbnhpZXR5Lm1lYS52bGlkLCBhbnhpZXR5Lm1sYSA9IGFueGlldHkubWxhLnZsaWQsIA0KICAgICAgICAgICAgICAgICAgYW54aWV0eSA9IGFueGlldHkudmxpZCwgc2VsZi5lZmZpY2FjeSA9IGVmZmljYWN5LnZsaWQsDQogICAgICAgICAgICAgICAgICB0ZWNobm9sb2d5ID0gdGVjaC52bGlkLCBjb29wZXJhdGl2ZSA9IGNvb3BlcmF0aXZlLnZsaWQsDQogICAgICAgICAgICAgICAgICBkZWR1Y3RpdmUgPSBkZWR1Y3RpdmUudmxpZCwgZGVtb25zdHJhdGlvbiA9IGRlbW8udmxpZCwNCiAgICAgICAgICAgICAgICAgIGluZHVjdGl2ZSA9IGluZHVjdGl2ZS52bGlkLCBpbnRlZ3JhdGUgPSBpbnRlZ3JhdGUudmxpZCwNCiAgICAgICAgICAgICAgICAgIGxlY3R1cmUgPSBsZWN0dXJlLnZsaWQsIHJlcGV0aXRpdmUgPSByZXBldGl2ZS52bGlkLCANCiAgICAgICAgICAgICAgICAgIGVuZ2FnZSA9IGVuZ2FnZS52bGlkLCByZXNvdXJjZSA9IHJlc291cmNlLnZsaWQpDQpyb3cubmFtZSA8LSBjKCJhbnhpZXR5Lm1lYSIsICJhbnhpZXR5Lm1sYSIsICJhbnhpZXR5IiwgInNlbGYuZWZmaWNhY3kiLCANCiAgICAgICAgICAgICAgInRlY2hub2xvZ3kiLCAiY29vcGVyYXRpdmUiLA0KICAgICAgICAgICAgICAiZGVkdWN0aXZlIiwgImRlbW9uc3RyYXRpb24iLCAiaW5kdWN0aXZlIiwgImludGVncmF0ZSIsDQogICAgICAgICAgICAgICJsZWN0dXJlIiwgInJlcGV0aXRpdmUiLCAiZW5nYWdlIiwgInJlc291cmNlIikNCmNvbC5uYW1lIDwtIGMoInN0ZC5hbGwubWluIiwgInB2YWwubWF4IiwgInNybXIiLCAiY2ZpIiwgICJ0bGkiKQ0Kcm93bmFtZXModmxpZC50YWJsZSkgPC0gcm93Lm5hbWUNCmNvbG5hbWVzKHZsaWQudGFibGUpIDwtIGNvbC5uYW1lDQpwYW5kZXIodmxpZC50YWJsZSkNCmBgYA0KDQpUaGUgY29uc3RydWN0IHZhbGlkaXR5IG9mIGFsbCBtdWx0aS1pdGVtIGluc3RydW1lbnRzIHdhcyBhc3Nlc3NlZCB1c2luZyBDb25maXJtYXRvcnkgRmFjdG9yIEFuYWx5c2lzIChDRkkpLiBUaGUgcmVzdWx0cyBjb25maXJtZWQgdGhhdCBtb3N0IHNjYWxlcyBtZWV0IGVzdGFibGlzaGVkIHBzeWNob21ldHJpYyBzdGFuZGFyZHMuIFRoZSBtb2pwcml0eSBvZiB0aGUga2V5IGZpdCBpbmRpY2VzLCBpbmNsdWRpbmcgQ0ZJIGFuZCBUTEksIGV4Y2VlZGVkIHRoZSByZWNvbW1lbmRlZCB0aHJlc2hvbGQgb2YgMC45MCwgd2hpbGUgdGhlIFNSTVIgZmVsbCBiZWxvdyB0aGUgMC4wOCBjdXRvZmYsIGluZGljYXRpbmcgYSBnb29kIG1vZGVsIGZpdC4gRnVydGhlcm1vcmUsIGFsbCBmYWN0b3IgbG9hZGluZ3Mgd2VyZSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IChwIDwgLjA1KSBhbmQgc3Vic3RhbnRpYWwgaW4gbWFnbml0dWRlIChleGNlZWRpbmcgMC40KSwgZGVtb25zdHJhdGluZyBzdHJvbmcgcmVsYXRpb25zaGlwcyBiZXR3ZWVuIHRoZSBpdGVtcyBhbmQgdGhlaXIgaW50ZW5kZWQgbGF0ZW50IGNvbnN0cnVjdHMuIEluIHN1bW1hcnksIHRoZSB2YWxpZGl0eSBhbmFseXNpcyBjb25maXJtcyB0aGF0IHRoZSBpbnN0cnVtZW50cyB1c2VkIGluIHRoaXMgc3R1ZHkgYXJlIHJvYnVzdCBhbmQgYXBwcm9wcmlhdGUgZm9yIG1lYXN1cmluZyB0aGVpciByZXNwZWN0aXZlIGNvbmNlcHRzLg0KDQoqKlJlbWFya3MqKjogKDEpLiBUaGUgYWJvdmUgdmFsaWRpdHkgbWVhc3VyZXMgYmFzZWQgb24gdGhlIGl0ZW1zIGZvbGxvdyBtdWx0aS12YXJpYXRlIG5vcm1hbCBkaXN0cmlidXRpb24sIFRoaXMgaXMgYSBzdHJvbmcgYXNzdW1wdGlvbi4gVGhlIGl0ZW1zIGluIGVhY2ggaW5zdHJ1bWVudCBhcmUgbm90IGNvbnRpbm91cy4gVGhpcyBpbmZsdWVuY2VzIHNvbWUgb2YgdGhlIHZhbGlkaXR5IG1lYXN1cmUuICgyKS4gSW4gcHJhY3RpY2UsIHdlIGNhbiB1c2Ugc29tZSBkZXNjcmlwdGl2ZSBhcHByb2FjaGVzIHRvIHZpc3VhbCBjaGVjayB3aXRoIGFzc3VtaW5nIG11bHRpLXZhcmlhdGUgbm9ybWFsaXR5LiANCg0KDQojIyBSZWxpYW5iaWxpdHkgQW5hbHlzaXMNCg0KKipSZWxpYWJpbGl0eSoqIG9mIGEgbXVsdGktaXRlbSBzdXJ2ZXkgaW5zdHJ1bWVudCBhbnN3ZXJzIHRoZSBxdWVzdGlvbjogIklmIEkgbWVhc3VyZSB0aGUgc2FtZSB0aGluZyBtdWx0aXBsZSB0aW1lcywgd2lsbCBJIGdldCBhIGNvbnNpc3RlbnQgcmVzdWx0PyIgSXQgbWVhc3VyZXMgaG93IHdlbGwgdGhlIGl0ZW1zIHRoYXQgYXJlIHN1cHBvc2VkIHRvIG1lYXN1cmUgdGhlIHNhbWUgY29uc3RydWN0IGhhbmcgdG9nZXRoZXIuIA0KDQoqKkludGVybmFsIENvbnNpc3RlbmN5KiogaXMgdGhlIG1vc3QgY29tbW9uIGFzc2Vzc21lbnQgZm9yIGEgc3VydmV5IGFkbWluaXN0ZXJlZCBvbmNlLiBJdCBtZWFzdXJlcyB0aGUgZGVncmVlIHRvIHdoaWNoIGl0ZW1zIGluIGEgc2NhbGUgYXJlIGNvcnJlbGF0ZWQgd2l0aCBlYWNoIG90aGVyLiBUd28gd2VsbC1rbm93biBpbnRlcm5hbCBjb25zaXN0ZW5jeSBtZWFzdXJlcyBhcmUgQ3JvbmJhY2gncyBBbHBoYSAoQ3JvbmFiY2ssIDE5NTEpIGFuZCBNY0RvbmFsZCdzIE9tZWdhICgxOTk5KS4gKipNY0RvbmFsZCdzIE9tZWdhKiogaXMgbW9yZSByb2J1c3QgdGhhbiAqKkNyb25iYWNoJ3MgQWxwaGEqKi4gIA0KDQoqKkNyb25iYWNoJ3MgQWxwaGEqKiBhbmQgKipNY0RvbmFsZCdzIE9tZWdhKiogdHlwaWNhbGx5IHJhbmdlIGZyb20gMCB0byAxLiBUaGUgc3VnZ2VzdGVkIGN1dC1vZmZzIGFyZSBnaXZlbiBiZWxvdy4NCg0KKiBgPiAwLjlgOiBFeGNlbGxlbnQNCg0KKiBgMC44IC0gMC45YDogR29vZA0KDQoqIGAwLjcgLSAwLjhgOiBBY2NlcHRhYmxlDQoNCiogYDwgMC43YDogUG9vciAobWF5IGhhdmUgaXRlbXMgdGhhdCBkb24ndCAiYmVsb25nIikNCg0KDQpgYGB7ciBlY2hvID0gRkFMU0UsIGV2YWwgPSBUUlVFfQ0KUmVsaWFiaWxpdHkuZnVuID0gZnVuY3Rpb24oZGF0YWZyYW1lKXsNCiAgb21lZ2EgPC0gcHN5Y2g6Om9tZWdhKGRhdGFmcmFtZVssIC0xXSwgbmZhY3RvcnMgPSAxLCBwbG90ID0gRkFMU0UpDQogIHJlbGlhYiA8LWNiaW5kKG9tZWdhJGFscGhhLCBvbWVnYSRvbWVnYS50b3QpDQogIHJlbGlhYg0KICB9DQpgYGANCg0KDQpgYGB7ciBlY2hvID0gVFJVRSwgZXZhbCA9IFRSVUUsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZz1GQUxTRX0NCmFueGlldHkubWVhLnJlbCA8LSBSZWxpYWJpbGl0eS5mdW4oQW54aWV0eS5tZWEpDQphbnhpZXR5Lm1sYS5yZWwgPC0gUmVsaWFiaWxpdHkuZnVuKEFueGlldHkubWxhKQ0KYW54aWV0eS5yZWwgPC0gUmVsaWFiaWxpdHkuZnVuKENvbXAuQW54aWV0eSkNCmVmZmljYWN5LnJlbCA8LSBSZWxpYWJpbGl0eS5mdW4oQ29tcC5TZWxmRWZmaWNhY3kpDQp0ZWNoLnJlbCA8LSBSZWxpYWJpbGl0eS5mdW4oQ29tcC5UZWNobm9sb2d5KQ0KY29vcGVyYXRpdmUucmVsIDwtIFJlbGlhYmlsaXR5LmZ1bihDb21wLkNvb3BvcmF0aXZlKQ0KZGVkdWN0aXZlLnJlbCA8LSBSZWxpYWJpbGl0eS5mdW4oQ29tcC5EZWR1Y3RpdmUpDQpkZW1vLnJlbCA8LSBSZWxpYWJpbGl0eS5mdW4oQ29tcC5EZW1vbnN0cmF0aW9uKQ0KaW5kdWN0aXZlLnJlbCA8LSBSZWxpYWJpbGl0eS5mdW4oQ29tcC5JbmR1Y3RpdmUpDQppbnRlZ3JhdGUucmVsIDwtIFJlbGlhYmlsaXR5LmZ1bihDb21wLkludGVncmF0aXZlKQ0KbGVjdHVyZS5yZWwgPC0gUmVsaWFiaWxpdHkuZnVuKENvbXAuTGVjdHVyZVR5cGUpDQpyZXBldGl2ZS5yZWwgPC0gUmVsaWFiaWxpdHkuZnVuKENvbXAuUmVwZXRpdGl2ZSkNCiNhZnRlci5yZWwgPC0gUmVsaWFiaWxpdHkuZnVuKENvbXAuQWZ0ZXJDbGFzcykNCiNpbi5jbGFzcy5yZWwgPC0gUmVsaWFiaWxpdHkuZnVuKENvbXAuSW5DbGFzcykNCmVuZ2FnZS5yZWwgPC0gUmVsaWFiaWxpdHkuZnVuKENvbXAuRW5nYWdlKQ0KcmVzb3VyY2UucmVsIDwtIFJlbGlhYmlsaXR5LmZ1bihDb21wLlJlc291cmNlKQ0KIyMNClJlbC50YWJsZSA8LXJiaW5kKGFueGlldHkubWVhID0gYW54aWV0eS5tZWEucmVsLCBhbnhpZXR5Lm1sYSA9IGFueGlldHkubWxhLnJlbCwNCiAgICAgICAgICAgICAgICAgIGFueGlldHkgPSBhbnhpZXR5LnJlbCwgc2VsZi5lZmZpY2FjeSA9IGVmZmljYWN5LnJlbCwNCiAgICAgICAgICAgICAgICAgIHRlY2hub2xvZ3kgPSB0ZWNoLnJlbCwgY29vcGVyYXRpdmUgPSBjb29wZXJhdGl2ZS5yZWwsDQogICAgICAgICAgICAgICAgICBkZWR1Y3RpdmUgPSBkZWR1Y3RpdmUucmVsLCBkZW1vbnN0cmF0aW9uID0gZGVtby5yZWwsDQogICAgICAgICAgICAgICAgICBpbmR1Y3RpdmUgPSBpbmR1Y3RpdmUucmVsLCBpbnRlZ3JhdGUgPSBpbnRlZ3JhdGUucmVsLA0KICAgICAgICAgICAgICAgICAgbGVjdHVyZSA9IGxlY3R1cmUucmVsLCByZXBldGl0aXZlID0gcmVwZXRpdmUucmVsLCANCiAgICAgICAgICAgICAgICAgIGVuZ2FnZSA9IGVuZ2FnZS5yZWwsIHJlc291cmNlID0gcmVzb3VyY2UucmVsKQ0Kcm93Lm5hbWUgPC0gYygiYW54aWV0eS5tZWEiLCAiYW54aWV0eS5tbGEiLA0KICAgICAgICAgICAgICAiYW54aWV0eSIsICJzZWxmLmVmZmljYWN5IiwgInRlY2hub2xvZ3kiLCAiY29vcGVyYXRpdmUiLA0KICAgICAgICAgICAgICAiZGVkdWN0aXZlIiwgImRlbW9uc3RyYXRpb24iLCAiaW5kdWN0aXZlIiwgImludGVncmF0ZSIsDQogICAgICAgICAgICAgICJsZWN0dXJlIiwgInJlcGV0aXRpdmUiLCAiZW5nYWdlIiwgInJlc291cmNlIikNCmNvbC5uYW1lIDwtIGMoIkNyb25iYWNoIGFscGhhIiwgIk1jRG9uYWxkJ3MgT21lZ2EiKQ0Kcm93bmFtZXMoUmVsLnRhYmxlKSA8LSByb3cubmFtZQ0KY29sbmFtZXMoUmVsLnRhYmxlKSA8LSBjb2wubmFtZQ0KcGFuZGVyKFJlbC50YWJsZSkNCmBgYA0KDQpXZSBjYW4gc2VlIGZyb20gdGhlIGFib3ZlIHRhYmxlIHRoYXQgYWxsIGNhbGN1bGF0ZWQgY29lZmZpY2llbnRzIGV4Y2VlZGVkIHRoZSByZWNvbW1lbmRlZCB0aHJlc2hvbGQgb2YgMC43LCBpbmRpY2F0aW5nIGdvb2QgcmVsaWFiaWxpdHkuIFRoZSByZXN1bHRzIGNvbmZpcm0gdGhhdCB0aGUgaW5zdHJ1bWVudHMgdXNlZCBpbiB0aGlzIHN0dWR5IGRlbW9uc3RyYXRlIHN0cm9uZyBpbnRlcm5hbCBjb25zaXN0ZW5jeSwgbWVhbmluZyB0aGUgaXRlbXMgd2l0aGluIGVhY2ggc2NhbGUgcmVsaWFibHkgbWVhc3VyZSB0aGUgc2FtZSB1bmRlcmx5aW5nIGNvbnN0cnVjdC4NCg0KDQoNCiMgQ29tcG9zaXRlIFNjb3JpbmcNCg0KVGhlIGNvcmUgcHVycG9zZSBvZiBjb25zdHJ1Y3RpbmcgbXVsdGktaXRlbSBzdXJ2ZXlzIGlzIHRvIG1lYXN1cmUgY29tcGxleCBjb25jZXB0cyB3aXRoIGdyZWF0ZXIgYWNjdXJhY3ksIHJlbGlhYmlsaXR5LCBhbmQgZGVwdGggdGhhbiBhIHNpbmdsZSBxdWVzdGlvbiBldmVyIGNvdWxkLiBBbGwgaW5zdHJ1bWVudHMgdXNlZCBpbiB0aGlzIHN0dWR5IGFyZSBiYXNlZCBvbiBhIHNpbmdsZS1mYWN0b3IgY29uc3RydWN0IHVzaW5nIHRoZSBMaWtlcnQgc2NhbGVzLiBUaGUgY29tbW9ubHkgdXNlZCBtZXRob2RzIGZvciBkZWZpbmluZyBzaW5nbGUgaW5kZXggdG8gY2FwdHVyZSB0aGUgaW5mb3JtYXRpb24gb2YgdGhlIHNpbmdsZS1mYWN0b3IgY29uc3RydWN0IGFyZSBjbGFzc2lmaWVkIGluIHRocmVlIGNhdGVnb3JpZXMNCg0KIyMgU3VtbWluZyB0aGUgUmF3IExpa2VydCBTY29yZXMNCg0KVGhlIHNpbXBsZXN0IGFwcHJvYWNoIGlzIHRvIHN1bSB0aGUgcmF3IExpa2VydCBzY29yZXMgaW50byBhIGNvbXBvc2l0ZSBzY29yZSB0aGF0IHJlcHJlc2VudHMgYSBzaW5nbGUgZmFjdG9yIHdpdGhpbiB0aGUgc3VydmV5IGNvbnN0cnVjdC4gVGhpcyBtZXRob2QgaXMgdmFsaWQgcHJvdmlkZWQgdGhhdCBhbGwgcXVlc3Rpb25uYWlyZSBpdGVtcyBhcmUgZXF1YWxseSBpbXBvcnRhbnQsIGFzIGVhY2ggY2FwdHVyZXMgYSBzaW1pbGFyIGFtb3VudCBvZiBpbmZvcm1hdGlvbiBhYm91dCB0aGUgdW5kZXJseWluZyBmYWN0b3IuDQoNCkhvd2V2ZXIsIHRoaXMgYXBwcm9hY2ggaXMgdmlvbGF0ZWQgaW4gc2V2ZXJhbCBjcml0aWNhbCBzY2VuYXJpb3MsIGxlYWRpbmcgdG8gYSBiaWFzZWQgYW5kIHVucmVsaWFibGUgY29tcG9zaXRlIHNjb3JlLiBGb3IgZXhhbXBsZSwgICoqVmlvbGF0aW9uIG9mIEVxdWFsIEltcG9ydGFuY2UqKjogVGhlIGNvcmUgYXNzdW1wdGlvbiBpcyB0aGF0IGVhY2ggaXRlbSBpcyBhIGVxdWFsbHkgc3Ryb25nIGluZGljYXRvciBvZiB0aGUgY29uc3RydWN0LiBJbiByZWFsaXR5LCBpdGVtcyBvZnRlbiBoYXZlIGRpZmZlcmVudCBsZXZlbHMgb2YgaW1wb3J0YW5jZS4gU3VtbWluZyBpdGVtcyB3aXRoIGhpZ2ggYW5kIGxvdyBsZXZlbHMgb2YgaW1wb3J0YW5jZSBlcXVhbGx5IGdpdmVzIHVuZHVlIHdlaWdodCB0byB3ZWFrZXIgaW5kaWNhdG9ycywgZWZmZWN0aXZlbHkgZGlsdXRpbmcgdGhlIGNvbXBvc2l0ZSBzY29yZSB3aXRoIG5vaXNlIGFuZCByZWR1Y2luZyBpdHMgdmFsaWRpdHkuIA0KDQoNCiMjIEZBIEFwcHJvYWNoDQoNCkNvbmZpcm1hdG9yeSBGYWN0b3IgQW5hbHlzaXMgKENGQSkgaXMgYSB2ZXJ5IGNvbW1vbiBhbmQgb2Z0ZW4gcHJhY3RpY2FsIGFwcHJvYWNoIHRvIHZhbGlkYXRpbmcgc3VydmV5IGluc3RydW1lbnRzIGFuZCBjcmVhdGUgKHdlaWdodGVkKSBjb21wb3NpdGUgc2NvcmUuIEl0IGlzIGEgZGlzdHJpYnV0aW9uIGRlcGVuZGVudCBzdGF0aXN0aWNhbCBtZXRob2QuIEhvd2V2ZXIsIGl0IGNvbWVzIHdpdGggYSBzZXQgb2YgZGlzdGluY3Qgc29tZSBkaXNhZHZhbnRhZ2VzIHBhcnRpY3VsYXJseSB0aGUgYXNzdW1wdGlvbiBvZiBtdWx0aS12YXJpYXRlIG5vcm1hbCBkaXN0cmlidXRpb24uIEZhY3RvciBsb2FkaW5ncyBpbiBDRkEgYXJlIGVzdGltYXRlZCBiYXNlZCBvbiB0aGUgbWF4aW11bSBsaWtlbGlob29kIHdoaWNoIGlzIGRlZmluZWQgYmFzZWQgb24gbXVsdGl2YXJpYXRlIG5vcm1hbCBkaXN0cmlidXRpb24uDQoNCldlIGhhdmUgdXNlZCBDRkEgdG8gdmFsaWRhdGUgdGhlIGluc3RydW1lbnQuIFNpbmNlIGFsbCBpbnN0cnVtZW50cyBpbiB0aGlzIHN0dWR5IGFyZSBzaW5nbGUtZmFjdG9yIGNvbnN0cnVjdHMsIHdlIHdpbGwgY2FsY3VsYXRlIHRoZSBzaW5nbGUgY29tcG9zaXRlIHNjb3JlIGZvciBlYWNoIGluc3RydW1lbnQgdXNpbmcgQ0ZBLg0KDQoNCiMjIFBDQSBBcHByb2FjaCANCg0KUENBIGlzIGEgZGlzdHJpYnV0aW9uLWZyZWUgbWV0aG9kIHdoaWNoIHVzZXMgYSBtYXRoZW1hdGljYWwgdHJhbnNmb3JtYXRpb24gKG9ydGhvZ29uYWwgcm90YXRpb24pIHRvIG9idGFpbiBhIG5ldyBjb29yZGluYXRlIHN5c3RlbSBzdWNoIHRoYXQgdGhlIGZpcnN0IG5ldyBheGlzIChQcmluY2lwYWwgQ29tcG9uZW50IDEpIHBvaW50cyBpbiB0aGUgZGlyZWN0aW9uIG9mIHRoZSBtYXhpbXVtIHZhcmlhbmNlIGluIHRoZSBkYXRhLiBUaGUgc2Vjb25kIGF4aXMgaXMgb3J0aG9nb25hbCB0byB0aGUgZmlyc3QgYW5kIHBvaW50cyBpbiB0aGUgZGlyZWN0aW9uIG9mIHRoZSBuZXh0IGdyZWF0ZXN0IHZhcmlhbmNlLCBhbmQgc28gb24uIFRoZSBuZXcgYXhlcyAoY29tcG9uZW50cykgYXJlIGxpbmVhciBjb21iaW5hdGlvbnMgb2YgdGhlIG9yaWdpbmFsIHZhcmlhYmxlcy4gQ29uc2VxdWVudGx5LCBhIGstaXRlbSBpbnN0cnVtZW50IHdpbGwgZ2VuZXJhdGUgayBwcmluY2lwYWwgY29tcG9uZW50cy4NCg0KQWx0aG91Z2ggdGhlcmUgZGViYXRlcyBvbiB1c2luZyBQQ0EgaW4gcHN5Y2hvbWV0cmljcywgdGhlIGVhcmxpZXN0IGFwcGxpY2F0aW9ucyBvZiBQQ0EgaW4gc3VydmV5IHJlc2VhcmNoIGNhbiBiZSB0cmFjZWQgYmFjayB0byAxOTUwcyAoU3RvdWZmZXIgZXQgYWwuLCAxOTUwOyBDYXR0ZWxsLCAxOTUyOyBEdW5jYW4sIDE5ICkuIFRoZSBnb2FsIHdhcyBjb25zaXN0ZW50bHkgdGhlIHNhbWUgYXMgaXQgaXMgdG9kYXk6IHRvIHVuY292ZXIgdGhlIHNpbXBsZSwgbGF0ZW50IHN0cnVjdHVyZXMgdGhhdCB1bmRlcmxpZSB0aGUgY29tcGxleCBjb3JyZWxhdGlvbnMgYW1vbmcgbWFueSBvYnNlcnZlZCBzdXJ2ZXkgcXVlc3Rpb25zLg0KDQo8Zm9udCBjb2xvciA9ICJyZWQiPioqQWRqdXN0aW5nIERpcmVjdGlvbiBvZiBQQ3MqKjwvZm9udD4NCg0KUHJpbmNpcGFsIENvbXBvbmVudHMgKFBDcykgYXJlIG5ldywgdW5jb3JyZWxhdGVkIGF4ZXMsIHdoZXJlYXMgTGlrZXJ0IHNjb3JlcyBhcmUgb3JkaW5hbCByYXRpbmcgc2NhbGVzLiBXaGVuIHVzaW5nIFBDcyB0byByZXByZXNlbnQgdGhlc2UgcmF0aW5nIHNjYWxlcywgdGhlaXIgZGlyZWN0aW9uIG11c3QgYmUgYWxpZ25lZC4gQSBzaW1wbGUgbWV0aG9kIHRvIGRldGVybWluZSBpZiBhIFBDJ3MgZGlyZWN0aW9uIG5lZWRzIHRvIGJlIHJldmVyc2VkIGlzIHRvIGV4YW1pbmUgdGhlIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50cyBiZXR3ZWVuIHRoZSBuYWl2ZSBjb21wb3NpdGUgYXZlcmFnZSBzY29yZXMgYW5kIHRoZSBQQyBzY29yZXMuIElmIHRoZSBjb3JyZWxhdGlvbiBpcyBuZWdhdGl2ZSwgdGhlIGNvcnJlc3BvbmRpbmcgUEMgc2hvdWxkIGJlIHJldmVyc2VkOyBvdGhlcndpc2UsIHRoZSBkZWZhdWx0IGF4aXMgc2hvdWxkIGJlIHJldGFpbmVkLg0KDQoqKkNvbXBvc2l0ZSBTY29yaW5nIFVzaW5nIFRoZSBmaXJzdCBQcmluY2lwYWwgQ29tcG9uZW50IChQQzEpKioNCg0KVGhpcyBhcHByb2FjaCBoYXMgYmVlbiBlbXBsb3llZCBzaW5jZSB0aGUgMTk1MHMgKGUuZy4sIEd1dHRtYW4sIDE5NTQ7IEhpcnNjaGJlcmcgJiBTdGFuZGlzaCwgMTk1OTsgRHVuY2FuLCAxOTYxKS4gVGhlIHJhdGlvbmFsZSBmb3IgdXNpbmcgdGhlIGZpcnN0IHByaW5jaXBhbCBjb21wb25lbnQgaXMgdGhhdCBpdCBhY2NvdW50cyBmb3IgdGhlIG1heGltdW0gdmFyaWFuY2UgaW4gdGhlIGRhdGEgYW5kIGNvbnN0aXR1dGVzIGEgbGluZWFyIGNvbWJpbmF0aW9uIG9mIGFsbCBpdGVtcy4gTXVjaCBsaWtlIGluIGNvbmZpcm1hdG9yeSBmYWN0b3IgYW5hbHlzaXMgKENGQSksIHRoZSBmaXJzdCBwcmluY2lwYWwgY29tcG9uZW50IGNhbiBiZSBpbnRlcnByZXRlZCBhcyBhIHdlaWdodGVkIGF2ZXJhZ2Ugb2YgaW5kaXZpZHVhbCBpdGVtIHNjb3Jlcy4NCg0KDQoqKkNvbXBvc2l0ZSBTY29yaW5nIFVzaW5nIFdlaWdodGVkIEF2ZXJhZ2Ugb2YgSXRlbSBTY29yZXMgQWNyb3NzIEFsbCBQQ3M6IDxmb250IGNvbG9yID0gInJlZCI+RG91Ymx5IFdlaWdodGVkIEF2ZXJhZ2U8L2ZvbnQ+KioNCg0KSW4gbWFueSByZWFsLXdvcmxkIGRhdGFzZXRzLCB0aGUgdW5kZXJseWluZyBjb25zdHJ1Y3RzIGFyZSBpbmhlcmVudGx5IG11bHRpZGltZW5zaW9uYWwuIENvbnNlcXVlbnRseSwgbGltaXRpbmcgdGhlIGFuYWx5c2lzIHRvIHRoZSBmaXJzdCBwcmluY2lwYWwgY29tcG9uZW50IG1lYW5zIGRpc2NhcmRpbmcgc3RydWN0dXJlZCBpbmZvcm1hdGlvbiBjYXB0dXJlZCBieSBzdWJzZXF1ZW50IGNvbXBvbmVudHMgKFBDMiwgUEMzLCBldGMuKS4gQSBjb21wb3NpdGUgc2NvcmUgdGhhdCBpbnRlZ3JhdGVzIGFsbCBzaWduaWZpY2FudCBjb21wb25lbnRzIG9mZmVycyBhIG1vcmUgaG9saXN0aWMgYW5kIGFjY3VyYXRlIHN1bW1hcnkgbWVhc3VyZS4gVGhlIHByaW1hcnkgYmFycmllciB0byB0aGUgd2lkZXNwcmVhZCBhZG9wdGlvbiBvZiB0aGlzIG1ldGhvZCBpcyB0aGUgY2hhbGxlbmdlIGFzc29jaWF0ZWQgd2l0aCBpbnRlcnByZXRpbmcgdGhlIGNvbXBvc2l0ZSBpbmRleCdzIHN0cnVjdHVyZS4NCg0KDQoNCiMjIENvbXBvc2l0ZSBTY29yZXMgVG8gQmUgQ3JlYXRlZA0KDQpXZSB3aWxsIGdlbmVyYXRlIGZvdXIgdHlwZXMgb2YgY29tcG9zaXRlIHNjb3JlcyBmb3IgZWFjaCBvZiB0aGUgMTEgaW5zdHJ1bWVudHMgZm9yIHRoZSBwdXJwb3NlIG9mIGVtcGlyaWNhbCBjb21wYXJpc29uLg0KDQoqICoqYXZnKio6IFRoZSBhdmVyYWdlIG9mIHRoZSByYXcgaXRlbSBzY29yZXMuDQoqICoqY2ZhKio6IFRoZSBleHRyYWN0IGNvbmZpcm1hdG9yeSBmYWN0b3IgYW5hbHlzaXMgKGNmYSkgc2NvcmUgKGFsbCBpbnN0cnVtZW50cyBhcmUgYmFzZWQgb24gdGhlIHNpbmdsZS1mYWN0b3IgY29uc3RydWN0KS4NCiogKipwY2ExKio6IFRoZSBmaXJzdCBwcmluY2lwYWwgY29tcG9uZW50IHNjb3Jlcy4NCiogKipwY2Eud3QqKjogVGhlIHdlaWdodGVkIGF2ZXJhZ2Ugb2YgcGNhIHNjb3JlcyBhY3Jvc3MgYWxsIHByaW5jaXBhbCBjb21wb25lbnRzLg0KDQoNCmBgYHtyIGVjaG8gPSBUUlVFLCBldmFsID0gVFJVRX0NCiMjIyMjDQogc2NvcmVzID0gZnVuY3Rpb24oZGYsIGRuKXsNCiAgIyMjIyMjIyMjIyMjIyMjDQogICMgbWVhbiBzY29yZQ0KICAjIyMjIyMjIyMjIyMjIw0KICBkZi5tZWFuIDwtIHJvd01lYW5zKGRmWywgLTFdKQ0KICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiAgIyMgc2luZ2xlIGZhY3RvciBzY29yZQ0KICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KICB4LnZhciA8LSBuYW1lcyhkZlssIC0xXSkNCiAgbjAgPC0gbGVuZ3RoKHgudmFyKQ0KICBjZmEubW9kZWwgPC0gIHBhc3RlKCJsYXRlbnQgPX4iLCBwYXN0ZSh4LnZhciwgY29sbGFwc2UgPSAiICsgIikpDQogIGNmYS5maXQgPC0gY2ZhKGNmYS5tb2RlbCwgZGF0YSA9IGRmWywgLTFdLCBlc3RpbWF0b3IgPSAiTUxNIikNCiAgY29tcG9zaXRlLmNmYSA8LSBsYXZQcmVkaWN0KGNmYS5maXQpDQogICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQogICMgcGNhIGFuYWx5c2lzDQogICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQogIHBjYS5tZGwgPC0gcHJjb21wKGRmWywtMV0sIHNjYWxlID0gVFJVRSkNCiAgcGNhMCA8LSBwY2EubWRsJHhbLCAxXQ0KICByMCA9IGNvcihwY2EwLCBkZi5tZWFuKQ0KICBpZihyMCA8IDApIHsNCiAgICAgcGNhLmFsbCA8LSAtcGNhLm1kbCR4DQogIH1lbHNlew0KICAgIHBjYS5hbGwgPC0gcGNhLm1kbCR4DQogIH0NCiAgZmlyc3QucGNhID0gcGNhLmFsbFssMV0NCiAgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiAgIyB3ZWlnaHRlZCBwY2Egc2NvcmUNCiAgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiAgdmFyLmV4cGxhaW5lZCA8LSgocGNhLm1kbCRzZGV2KV4yKSAvIHN1bSgocGNhLm1kbCRzZGV2KV4yKSAjDQogIGNvbXBvc2l0ZV93ZWlnaHRlZF9wY2EgPC0gYXMubWF0cml4KHBjYS5hbGwpICUqJSAodmFyLmV4cGxhaW5lZCkNCg0KICBvdXRkYXRhIDwtIGFzLmRhdGEuZnJhbWUoY2JpbmQoYXZnID0gZGYubWVhbiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICBwY2ExID0gZmlyc3QucGNhLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHd0LnBjYSA9IGFzLnZlY3Rvcihjb21wb3NpdGVfd2VpZ2h0ZWRfcGNhKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICBjZmEgPSBhcy52ZWN0b3IoY29tcG9zaXRlLmNmYSkpKQ0KICBuYW1lcyhvdXRkYXRhKSA8LSBwYXN0ZTAoZG4sIi4iLCBuYW1lcyhvdXRkYXRhKSwgc2VwID0gIiIpDQogIG91dGRhdGENCiAgfQ0KIyMjDQpBbnhpZXR5Lm1lYS5zY29yZSA9IHNjb3JlcyhBbnhpZXR5Lm1lYSwgIkFueGlldHkubWVhIikNCkFueGlldHkubWxhLnNjb3JlID0gc2NvcmVzKEFueGlldHkubWxhLCAiQW54aWV0eS5tbGEiKQ0KQW54aWV0eS5zY29yZSA9IHNjb3JlcyhDb21wLkFueGlldHksICJBbnhpZXR5IikNClNlbGZFZmZpY2FjeS5zY29yZSA9IHNjb3JlcyhDb21wLlNlbGZFZmZpY2FjeTAsICJTZWxmRWZmaWNhY3kiKQ0KVGVjaG5vbG9neS5zY29yZSA9IHNjb3JlcyhDb21wLlRlY2hub2xvZ3ksICJUZWNobm9sb2d5IikNCkNvb3BvcmF0aXZlLnNjb3JlID0gc2NvcmVzKENvbXAuQ29vcG9yYXRpdmUsICJDb29wb3JhdGl2ZSIpDQpEZWR1Y3RpdmUuc2NvcmUgPSBzY29yZXMoQ29tcC5EZWR1Y3RpdmUsICJEZWR1Y3RpdmUiKQ0KRGVtb25zdHJhdGlvbi5zY29yZSA9IHNjb3JlcyhDb21wLkRlbW9uc3RyYXRpb24sICJEZW1vbnN0cmF0aW9uIikNCkluZHVjdGl2ZS5zY29yZSA9IHNjb3JlcyhDb21wLkluZHVjdGl2ZSwgIkluZHVjdGl2ZSIpDQpJbnRlZ3JhdGl2ZS5zY29yZSA9IHNjb3JlcyhDb21wLkludGVncmF0aXZlLCAiSW50ZWdyYXRpdmUiKQ0KTGVjdHVyZVR5cGUuc2NvcmUgPSBzY29yZXMoQ29tcC5MZWN0dXJlVHlwZSwgIkxlY3R1cmVUeXBlIikNClJlcGV0aXRpdmUuc2NvcmUgPSBzY29yZXMoQ29tcC5SZXBldGl0aXZlLCAiUmVwZXRpdGl2ZSIpDQpFbmdhZ2Uuc2NvcmUgPSBzY29yZXMoQ29tcC5FbmdhZ2UsICJFbmdhZ2UiKQ0KUmVzb3VyY2Uuc2NvcmUgPSBzY29yZXMoQ29tcC5SZXNvdXJjZSwgIlJlc291cmNlIikNCiMjDQpmaW5hbERhdCA8LSBjYmluZChkZW1vZ3JhcGhpY3MsIEFueGlldHkuc2NvcmUsIEFueGlldHkubWVhLnNjb3JlLA0KICAgICAgICAgICAgICAgICAgQW54aWV0eS5tbGEuc2NvcmUsIFNlbGZFZmZpY2FjeS5zY29yZSwgVGVjaG5vbG9neS5zY29yZSwNCiAgICAgICAgICAgICAgICAgIENvb3BvcmF0aXZlLnNjb3JlLCBEZWR1Y3RpdmUuc2NvcmUsIERlbW9uc3RyYXRpb24uc2NvcmUsSW5kdWN0aXZlLnNjb3JlLA0KICAgICAgICAgICAgICAgICAgSW50ZWdyYXRpdmUuc2NvcmUsIExlY3R1cmVUeXBlLnNjb3JlLCBSZXBldGl0aXZlLnNjb3JlLA0KICAgICAgICAgICAgICAgICAgRW5nYWdlLnNjb3JlLCBSZXNvdXJjZS5zY29yZSkNCmBgYA0KDQoNCg0KYGBge3IgZWNobyA9IEZBTFNFLCBldmFsID0gRkFMU0V9DQp3cml0ZS5jc3YoZmluYWxEYXQsICJDOlxcVXNlcnNcXDc1Q1BFTkdcXE9uZURyaXZlIC0gV2VzdCBDaGVzdGVyIFVuaXZlcnNpdHkgb2YgUEFcXERlc2t0b3BcXGNwZW5nXFxXQ1UtVGVhY2hpbmdcXDIwMjVGYWxsXFxNYXRoQXhpZXR5XFxjb21wbGV0ZUFueGlldHlEYXRhLmNzdiIpDQpgYGANCg0KDQoNCiMgU29tZSBHcmFwaGljYWwgRXhwbG9yYXRpb24NCg0KV2UgbmV4dCBleHBsb3JlIHRoZSBkaXN0cmlidXRpb25zIG9mIHRoZSBjcmVhdGVkIGNvbXBvc2l0ZSBzY29yZXMgYW5kIHBlcmZvcm0gc29tZSBlbXBpcmljYWwgY29tcGFyaXNvbnMuIFRoZSBwcmltYXJ5IGdvYWwgb2YgdGhpcyBzdXJ2ZXkgc3R1ZHkgaXMgdG8gaW52ZXN0aWdhdGUgZmFjdG9ycyB0aGF0IGFyZSBhc3NvY2lhdGVkIHdpdGggbWF0aGVtYXRpY3MgYW54aWV0eSAoTUEpIGxldmVscy4gVG8gdGhpcyBlbmQsIHdlIGFsc28gbG9vayB0aGUgZGlzdHJpYnV0aW9ucyBlYWNoIGluZGl2aWR1YWwgaXRlbXMgaW4gdGhlIE1BIGluc3RydW1lbnQuDQoNCg0KIyMgRGlzdHJpYnV0aW9ucyBvZiBDb21wb3NpdGUgU2NvcmVzDQoNClRoZSBmb2xsb3dpbmcgYXJlIGRpc3RyaWJ1dGlvbnMgb2YgZm91ciBnZW5lcmF0ZWQgY29tcG9zaXRlIHNjb3JlcyBhY3Jvc3MgYWxsIGluc3RydW1lbnRzLiBUaGUgcHVycG9zZSBpcyB0byBleGFtaW5lIHRoZSBiZWhhdmlvcnMgb2YgdGhlc2UgY29tcG9zaXRlIHNjb3JlcywgZXNwZWNpYWxseSB0aGUgZG91Ymx5IHdlaWdodGVkIGNvbXBvc2l0ZSBzY29yZSBiYXNlZCBvbiB0aGUgcHJpbmNpcGFsIGNvbXBvbmVudCBhbmFseXNpcy4NCg0KDQpgYGB7ciBlY2hvID0gRkFMU0V9DQojZmluYWwuYW54aWV0eS5kYXQgPC0gcmVhZC5jc3YoImh0dHBzOi8vcGVuZ2RzY2kuZ2l0aHViLmlvL01hdGhBbnhpZXR5L2NvbXBsZXRlQW54aWV0eURhdGEuY3N2IikNCmZpbmFsLmFueGlldHkuZGF0IDwtIGZpbmFsRGF0DQpgYGANCg0KDQpgYGB7cn0NCnBsb3RseS5mdW4gPC0gZnVuY3Rpb24oaW4uZGF0YSl7DQogICBpbi5hdmcgPC0gZGVuc2l0eShpbi5kYXRhWywxXSkNCiAgIGluLnBjMSA8LSBkZW5zaXR5KGluLmRhdGFbLDJdKQ0KICAgaW4ucGN3IDwtIGRlbnNpdHkoaW4uZGF0YVssM10pDQogICBpbi5jZmEgPC0gZGVuc2l0eShpbi5kYXRhWywgNF0pDQogICBkYXQubmFtZSA8LSBzdWIoIlxcLi4qIiwgIiIsbmFtZXMoaW4uZGF0YSlbMV0pICAjc3ViKCB0ZXh0KQ0KICAgIyBwbG90IGRlbnNpdHkgY3VydmVzDQogIGZpZyA8LSBwbG90X2x5KHggPSB+aW4uYXZnJHgsIHkgPSB+aW4uYXZnJHksIA0KICAgICAgICAgICAgICAgdHlwZSA9ICdzY2F0dGVyJywgDQogICAgICAgICAgICAgICBtb2RlID0gJ2xpbmVzJywgDQogICAgICAgICAgICAgICBuYW1lID0gJ2F2ZycsIA0KICAgICAgICAgICAgICAgZmlsbCA9ICd0b3plcm95JykgICU+JSANCiAgICAgICAgICAgIyBhZGRpbmcgbW9yZSBkZW5zaXR5IGN1cnZlcw0KICAgICAgIGFkZF90cmFjZSh4ID0gfmluLnBjMSR4LCB5ID0gfmluLnBjMSR5LCANCiAgICAgICAgICAgICAgICAgbmFtZSA9ICdwY2ExJywgDQogICAgICAgICAgICAgICAgIGZpbGwgPSAndG96ZXJveScpICAlPiUgDQogICAgICAgYWRkX3RyYWNlKHggPSB+aW4ucGN3JHgsIHkgPSB+aW4ucGN3JHksIA0KICAgICAgICAgICAgICAgICBuYW1lID0gJ3BjYS53dCcsIA0KICAgICAgICAgICAgICAgICBmaWxsID0gJ3RvemVyb3knKSAgJT4lIA0KICAgICAgIGFkZF90cmFjZSh4ID0gfmluLmNmYSR4LCB5ID0gfmluLmNmYSR5LCANCiAgICAgICAgICAgICAgICAgbmFtZSA9ICdjZmEnLCANCiAgICAgICAgICAgICAgICAgZmlsbCA9ICd0b3plcm95JykgICU+JSANCiAgICAgICBsYXlvdXQoeGF4aXMgPSBsaXN0KHRpdGxlID0gJ3Njb3JlcycpLA0KICAgICAgICAgICAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAnRGVuc2l0eScpLA0KICAgICAgICAgICAgICAjdGl0bGUgPSBkYXQubmFtZSwNCiAgICAgICAgICAgICAgIG1hcmdpbiA9IGxpc3QoDQogICAgICAgICAgICAgICAgICB0ID0gMTAwLCAgIyBBZGp1c3QgdGhpcyB2YWx1ZSB0byBpbmNyZWFzZSBvciBkZWNyZWFzZSB0aGUgdG9wIG1hcmdpbg0KICAgICAgICAgICAgICAgICAgYiA9IDUwLA0KICAgICAgICAgICAgICAgICAgbCA9IDUwLA0KICAgICAgICAgICAgICAgICAgciA9IDUwKQ0KICAgICAgICAgICAgICkNCiAgICAgZmlnDQogICAgIH0NCiMjIyMNCmluLmFueGlldHkubWVhID0gZmluYWwuYW54aWV0eS5kYXRbLCBjKCAiQW54aWV0eS5tZWEuYXZnIiwgIkFueGlldHkubWVhLnBjYTEiLCAiQW54aWV0eS5tZWEud3QucGNhIiwiQW54aWV0eS5tZWEuY2ZhIildDQppbi5hbnhpZXR5Lm1sYSA9IGZpbmFsLmFueGlldHkuZGF0WywgYygiQW54aWV0eS5tbGEuYXZnIiwiQW54aWV0eS5tbGEucGNhMSIsICJBbnhpZXR5Lm1sYS53dC5wY2EiLCJBbnhpZXR5Lm1sYS5jZmEiKV0NCiMjIw0KaW4uYW54aWV0eSA9IGZpbmFsLmFueGlldHkuZGF0WywgYyggIkFueGlldHkuYXZnIiwgIkFueGlldHkucGNhMSIsICJBbnhpZXR5Lnd0LnBjYSIsICJBbnhpZXR5LmNmYSIpXQ0KaW4uZWZmaWNhY3kgPSBmaW5hbC5hbnhpZXR5LmRhdFssIGMoICJTZWxmRWZmaWNhY3kuYXZnIiwgIlNlbGZFZmZpY2FjeS5wY2ExIiwiU2VsZkVmZmljYWN5Lnd0LnBjYSIsIlNlbGZFZmZpY2FjeS5jZmEiKV0NCmluLnRlY2hub2xvZ3kgPSBmaW5hbC5hbnhpZXR5LmRhdFssIGMoICJUZWNobm9sb2d5LmF2ZyIsIlRlY2hub2xvZ3kucGNhMSIsICJUZWNobm9sb2d5Lnd0LnBjYSIsIlRlY2hub2xvZ3kuY2ZhIildDQppbi5jb29wb3JhdGl2ZSA9IGZpbmFsLmFueGlldHkuZGF0WywgYygiQ29vcG9yYXRpdmUuYXZnIiwiQ29vcG9yYXRpdmUucGNhMSIsICJDb29wb3JhdGl2ZS53dC5wY2EiLCJDb29wb3JhdGl2ZS5jZmEiKV0NCmluLmRlZHVjdGl2ZSA9IGZpbmFsLmFueGlldHkuZGF0WywgYygiRGVkdWN0aXZlLmF2ZyIsIkRlZHVjdGl2ZS5wY2ExIiwiRGVkdWN0aXZlLnd0LnBjYSIsIkRlZHVjdGl2ZS5jZmEiKV0NCmluLmRlbW9uc3RyYXRpb24gPSBmaW5hbC5hbnhpZXR5LmRhdFssIGMoIkRlbW9uc3RyYXRpb24uYXZnIiwiRGVtb25zdHJhdGlvbi5wY2ExIiwiRGVtb25zdHJhdGlvbi53dC5wY2EiLCJEZW1vbnN0cmF0aW9uLmNmYSIpXQ0KaW4uaW5kdWN0aXZlID0gZmluYWwuYW54aWV0eS5kYXRbLCBjKCAiSW5kdWN0aXZlLmF2ZyIsIkluZHVjdGl2ZS5wY2ExIiwiSW5kdWN0aXZlLnd0LnBjYSIsIkluZHVjdGl2ZS5jZmEiKV0NCmluLmludGVncmF0aXZlID0gZmluYWwuYW54aWV0eS5kYXRbLCBjKCAiSW50ZWdyYXRpdmUuYXZnIiwgIkludGVncmF0aXZlLnBjYTEiLCJJbnRlZ3JhdGl2ZS53dC5wY2EiLCJJbnRlZ3JhdGl2ZS5jZmEiKV0NCmluLmxlY3R1cmVUeXBlID0gZmluYWwuYW54aWV0eS5kYXRbLCBjKCAiTGVjdHVyZVR5cGUuYXZnIiwgIkxlY3R1cmVUeXBlLnBjYTEiLCAiTGVjdHVyZVR5cGUud3QucGNhIiwiTGVjdHVyZVR5cGUuY2ZhIildDQppbi5yZXBldGl0aXZlID0gZmluYWwuYW54aWV0eS5kYXRbLCBjKCAiUmVwZXRpdGl2ZS5hdmciLCAiUmVwZXRpdGl2ZS5wY2ExIiwgIlJlcGV0aXRpdmUud3QucGNhIiwiUmVwZXRpdGl2ZS5jZmEiKV0NCmluLmVuZ2FnZSA9IGZpbmFsLmFueGlldHkuZGF0WywgYyggICJFbmdhZ2UuYXZnIiwgIkVuZ2FnZS5wY2ExIiwgIkVuZ2FnZS53dC5wY2EiLCJFbmdhZ2UuY2ZhIildDQppbi5yZXNvdXJjZSA9IGZpbmFsLmFueGlldHkuZGF0WywgYyggIlJlc291cmNlLmF2ZyIsICJSZXNvdXJjZS5wY2ExIiwgIlJlc291cmNlLnd0LnBjYSIsICJSZXNvdXJjZS5jZmEiKV0NCmBgYA0KDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9M30NCnAubWVhIDwtIHBsb3RseS5mdW4oaW4uYW54aWV0eS5tZWEpDQpwLm1sYSA8LSBwbG90bHkuZnVuKGluLmFueGlldHkubWxhKQ0KIyBBcnJhbmdlIGluIDF4MiBncmlkDQpzdWJwbG90KHAubWVhLCBwLm1sYSwgbnJvd3MgPSAxLCB0aXRsZVggPSBUUlVFLCB0aXRsZVkgPSBUUlVFLCBtYXJnaW4gPSAwLjEpICU+JQ0KICBsYXlvdXQoDQogICAgYW5ub3RhdGlvbnMgPSBsaXN0KA0KICAgICAgbGlzdCh4ID0gMC4wNSwgeSA9IC45OSwgdGV4dCA9ICJBbnhpZXR5Lm1lYSIsIA0KICAgICAgICAgICB4cmVmID0gInBhcGVyIiwgeXJlZiA9ICJwYXBlciIsIHNob3dhcnJvdyA9IEZBTFNFLCBmb250ID0gbGlzdChzaXplID0gMTQpKSwNCiAgICAgIGxpc3QoeCA9IDAuNzUsIHkgPSAwLjk5LCB0ZXh0ID0gIkFueGlldHkubWxhIiwgDQogICAgICAgICAgIHhyZWYgPSAicGFwZXIiLCB5cmVmID0gInBhcGVyIiwgc2hvd2Fycm93ID0gRkFMU0UsIGZvbnQgPSBsaXN0KHNpemUgPSAxNCkpDQogICAgKSwNCiAgICBzaG93bGVnZW5kID0gRkFMU0UNCiAgKQ0KYGBgDQoNCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD01fQ0KcDEgPC0gcGxvdGx5LmZ1bihpbi5hbnhpZXR5KQ0KcDIgPC0gcGxvdGx5LmZ1bihpbi5lZmZpY2FjeSkNCnAzIDwtIHBsb3RseS5mdW4oaW4udGVjaG5vbG9neSkNCnA0IDwtIHBsb3RseS5mdW4oaW4uY29vcG9yYXRpdmUpDQojIEFycmFuZ2UgaW4gMngyIGdyaWQNCnN1YnBsb3QocDEsIHAyLCBwMiwgcDQsIG5yb3dzID0gMiwgdGl0bGVYID0gVFJVRSwgdGl0bGVZID0gVFJVRSwgbWFyZ2luID0gMC4xKSAlPiUNCiAgbGF5b3V0KA0KICAgIGFubm90YXRpb25zID0gbGlzdCgNCiAgICAgIGxpc3QoeCA9IDAuMDUsIHkgPSAuOTksIHRleHQgPSAiQW54aWV0eSIsIA0KICAgICAgICAgICB4cmVmID0gInBhcGVyIiwgeXJlZiA9ICJwYXBlciIsIHNob3dhcnJvdyA9IEZBTFNFLCBmb250ID0gbGlzdChzaXplID0gMTQpKSwNCiAgICAgIGxpc3QoeCA9IDAuNzUsIHkgPSAwLjk5LCB0ZXh0ID0gIlNlbGYtZWZmaWNhY3kiLCANCiAgICAgICAgICAgeHJlZiA9ICJwYXBlciIsIHlyZWYgPSAicGFwZXIiLCBzaG93YXJyb3cgPSBGQUxTRSwgZm9udCA9IGxpc3Qoc2l6ZSA9IDE0KSksDQogICAgICBsaXN0KHggPSAwLjA1LCB5ID0gMC40LCB0ZXh0ID0gIlRlY2hub2xvZ3kiLCANCiAgICAgICAgICAgeHJlZiA9ICJwYXBlciIsIHlyZWYgPSAicGFwZXIiLCBzaG93YXJyb3cgPSBGQUxTRSwgZm9udCA9IGxpc3Qoc2l6ZSA9IDE0KSksDQogICAgICBsaXN0KHggPSAwLjc1LCB5ID0gMC40LCB0ZXh0ID0gIkNvb3Jwb3JhdGl2ZSIsIA0KICAgICAgICAgICB4cmVmID0gInBhcGVyIiwgeXJlZiA9ICJwYXBlciIsIHNob3dhcnJvdyA9IEZBTFNFLCBmb250ID0gbGlzdChzaXplID0gMTQpKQ0KICAgICksDQogICAgc2hvd2xlZ2VuZCA9IEZBTFNFDQogICkNCmBgYA0KDQoNCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD01fQ0KcDEgPC0gcGxvdGx5LmZ1bihpbi5kZWR1Y3RpdmUpDQpwMiA8LSBwbG90bHkuZnVuKGluLmRlbW9uc3RyYXRpb24pDQpwMyA8LSBwbG90bHkuZnVuKGluLmluZHVjdGl2ZSkNCnA0IDwtIHBsb3RseS5mdW4oaW4uaW50ZWdyYXRpdmUpDQojIEFycmFuZ2UgaW4gMngyIGdyaWQNCnN1YnBsb3QocDEsIHAyLCBwMiwgcDQsIG5yb3dzID0gMiwgdGl0bGVYID0gVFJVRSwgdGl0bGVZID0gVFJVRSwgbWFyZ2luID0gMC4xKSAlPiUNCiAgbGF5b3V0KA0KICAgIGFubm90YXRpb25zID0gbGlzdCgNCiAgICAgIGxpc3QoeCA9IDAuMDUsIHkgPSAuOTksIHRleHQgPSAiRGVkdWN0aXZlIiwgDQogICAgICAgICAgIHhyZWYgPSAicGFwZXIiLCB5cmVmID0gInBhcGVyIiwgc2hvd2Fycm93ID0gRkFMU0UsIGZvbnQgPSBsaXN0KHNpemUgPSAxNCkpLA0KICAgICAgbGlzdCh4ID0gMC43NSwgeSA9IDAuOTksIHRleHQgPSAiRGVtb25zdHJhdGl2ZSIsIA0KICAgICAgICAgICB4cmVmID0gInBhcGVyIiwgeXJlZiA9ICJwYXBlciIsIHNob3dhcnJvdyA9IEZBTFNFLCBmb250ID0gbGlzdChzaXplID0gMTQpKSwNCiAgICAgIGxpc3QoeCA9IDAuMDUsIHkgPSAwLjQsIHRleHQgPSAiSW5kdWN0aXZlIiwgDQogICAgICAgICAgIHhyZWYgPSAicGFwZXIiLCB5cmVmID0gInBhcGVyIiwgc2hvd2Fycm93ID0gRkFMU0UsIGZvbnQgPSBsaXN0KHNpemUgPSAxNCkpLA0KICAgICAgbGlzdCh4ID0gMC43NSwgeSA9IDAuNCwgdGV4dCA9ICJJbnRlcmdyYXRpdmUiLCANCiAgICAgICAgICAgeHJlZiA9ICJwYXBlciIsIHlyZWYgPSAicGFwZXIiLCBzaG93YXJyb3cgPSBGQUxTRSwgZm9udCA9IGxpc3Qoc2l6ZSA9IDE0KSkNCiAgICApLA0KICAgIHNob3dsZWdlbmQgPSBGQUxTRQ0KICApDQpgYGANCg0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTV9DQpwMSA8LSBwbG90bHkuZnVuKGluLmxlY3R1cmVUeXBlKQ0KcDIgPC0gcGxvdGx5LmZ1bihpbi5yZXBldGl0aXZlKQ0KcDMgPC0gcGxvdGx5LmZ1bihpbi5lbmdhZ2UpDQpwNCA8LSBwbG90bHkuZnVuKGluLnJlc291cmNlKQ0KIyBBcnJhbmdlIGluIDJ4MiBncmlkDQpzdWJwbG90KHAxLCBwMiwgcDIsIHA0LCBucm93cyA9IDIsIHRpdGxlWCA9IFRSVUUsIHRpdGxlWSA9IFRSVUUsIG1hcmdpbiA9IDAuMSkgJT4lDQogIGxheW91dCgNCiAgICBhbm5vdGF0aW9ucyA9IGxpc3QoDQogICAgICBsaXN0KHggPSAwLjA1LCB5ID0gLjk5LCB0ZXh0ID0gIkxlY3R1cmUgVHlwZSIsIA0KICAgICAgICAgICB4cmVmID0gInBhcGVyIiwgeXJlZiA9ICJwYXBlciIsIHNob3dhcnJvdyA9IEZBTFNFLCBmb250ID0gbGlzdChzaXplID0gMTQpKSwNCiAgICAgIGxpc3QoeCA9IDAuNzUsIHkgPSAwLjk5LCB0ZXh0ID0gIlJlcGV0YXRpdmUiLCANCiAgICAgICAgICAgeHJlZiA9ICJwYXBlciIsIHlyZWYgPSAicGFwZXIiLCBzaG93YXJyb3cgPSBGQUxTRSwgZm9udCA9IGxpc3Qoc2l6ZSA9IDE0KSksDQogICAgICBsaXN0KHggPSAwLjA1LCB5ID0gMC40LCB0ZXh0ID0gIkVuZ2FnZW1lbnQiLCANCiAgICAgICAgICAgeHJlZiA9ICJwYXBlciIsIHlyZWYgPSAicGFwZXIiLCBzaG93YXJyb3cgPSBGQUxTRSwgZm9udCA9IGxpc3Qoc2l6ZSA9IDE0KSksDQogICAgICBsaXN0KHggPSAwLjc1LCB5ID0gMC40LCB0ZXh0ID0gIlJlc291cmNlIiwgDQogICAgICAgICAgIHhyZWYgPSAicGFwZXIiLCB5cmVmID0gInBhcGVyIiwgc2hvd2Fycm93ID0gRkFMU0UsIGZvbnQgPSBsaXN0KHNpemUgPSAxNCkpDQogICAgKSwNCiAgICBzaG93bGVnZW5kID0gRkFMU0UNCiAgKQ0KYGBgDQoNClRoZXNlIGRlbnNpdHkgY3VydmVzIGlsbHVzdHJhdGUgdGhlIGRpc3RyaWJ1dGlvbnMgb2YgdGhlIGZvdXIgY29tcG9zaXRlIHNjb3JlcyAoKiphdmcsIGNmYSwgcGMxKiosIGFuZCAqKnBjYS53dCoqKSBmb3IgYWxsIHNpbmdsZS1mYWN0b3IgaW5zdHJ1bWVudHMgaW4gdGhlIHN1cnZleS4gVGhlICoqYXZnKiogaXMgYSBuYWl2ZSBtZWFzdXJlLCBkZXJpdmVkIGZyb20gdGhlIGFyaXRobWV0aWMgbWVhbiBvZiB0aGUgaXRlbSBzY29yZXMuIFRoZSAqKmNmYSoqIGFuZCAqKnBjMSoqIGNvbXBvc2l0ZXMgYXJlIHdlaWdodGVkIGF2ZXJhZ2VzLCB3aGVyZSB0aGUgd2VpZ2h0cyAobG9hZGluZ3MpIGFyZSBkZXJpdmVkIGZyb20gZGlzdGluY3QgbGF0ZW50IHZhcmlhYmxlIG1vZGVscy4gVGhlICoqcGNhLnd0IGNvbXBvc2l0KiplIGlzIGEgPGZvbnQgY29sb3I9InJlZCI+Kipkb3VibHkgd2VpZ2h0ZWQgYXZlcmFnZSoqPC9mb250PiwgYmFzZWQgb24gYm90aCB0aGUgb3JpZ2luYWwgaXRlbSBzY29yZXMgYW5kIGFsbCBvZiB0aGUgcmVzdWx0aW5nIHByaW5jaXBhbCBjb21wb25lbnRzLiANCg0KKiBUaHJlZSBtb2RlbC1iYXNlZCBjb21wb3NpdGUgc2NvcmVzICgqKmNmYSwgcGMxKiosIGFuZCAqKnBjYS53dCoqKSBhcmUgY2VudGVyZWQgYXQgMCBidXQgZXhoaWJpdCBkaWZmZXJlbnQgYmVoYXZpb3JzOg0KICArICoqcGMxKiogaGFzIHRoZSBsYXJnZXN0IHZhcmlhbmNlLg0KICArICoqY2ZhKiogaGFzIHRoZSBzbWFsbGVzdCB2YXJpYW5jZS4NCg0KKiAqKmF2ZyoqIGFuZCAqKnBjYS53dCoqIGJlaGF2ZSBzaW1pbGFybHksIGRpZmZlcmluZyBwcmltYXJpbHkgaW4gdGhlaXIgbG9jYXRpb25zLg0KDQpUaGUgY29tcG9zaXRlIHNjb3JlICoqYXZnKiogc2VydmVzIGFzIGEgcmVmZXJlbmNlIHBvaW50LCBhbmFsb2dvdXMgdG8gYW4gZW1waXJpY2FsIGRpc3RyaWJ1dGlvbiwgYXMgaXQgdXNlcyBhbGwgaXRlbSBzY29yZXMgZGlyZWN0bHkuIEluIGNvbnRyYXN0LCAqKnBjYS53dCoqIHVzZXMgYSBkb3VibHkgd2VpZ2h0ZWQgYXZlcmFnZSBvZiBhbGwgaXRlbSBzY29yZXMgd2l0aG91dCBpbXBvc2luZyBjb21wbGV4IGRpc3RyaWJ1dGlvbmFsIGFzc3VtcHRpb25zLiBUaGlzIGRlbW9uc3RyYXRlcyB0aGF0ICoqcGNhLnd0KiogaXMgYSByZWxpYWJsZSBhbmQgcm9idXN0IGNvbXBvc2l0ZSBzY29yZS4gRm9yIHRoZSByZW1haW5kZXIgb2YgdGhpcyByZXBvcnQsIHRoZSAqKnBjYS53dCoqIHNjb3JlIHdpbGwgYmUgdXNlZCwgd2l0aCAqKmNmYSoqIG9jY2FzaW9uYWxseSBlbXBsb3llZCBmb3IgaWxsdXN0cmF0aXZlIHB1cnBvc2VzIGZvciBzb21lIHNwZWNpYWwgY2FzZXMuDQoNCg0KDQojIyBEaXN0cmlidXRpb24gb2YgRGVtb2dyYXBoaWNzDQoNClRoZSBkaXN0cmlidXRpb24gb2YgZGVtb2dyYXBoaWMgZmFjdG9ycyBhcmUgcmVwb3J0ZWQgaW4gdGhlIGZvbGxvd2luZyBmaWd1cmVzLg0KDQpgYGB7cn0NCiMgRW5oYW5jZWQgaG92ZXIgaW5mb3JtYXRpb24NCkRlbW9ncmFwaGljLmJhciA8LWZ1bmN0aW9uKGluLmNhdCwgdmFybmFtZSl7DQogIGZyZXEudGJsIDwtIHRhYmxlKGluLmNhdCkNCiAgZGYgPC0gZGF0YS5mcmFtZSgNCiAgICAgIGNhdGVnb3J5IDwtIG5hbWVzKGZyZXEudGJsKSwNCiAgICAgIHZhbHVlcyA8LSBhcy52ZWN0b3IoZnJlcS50YmwpDQogICkNCiAgIyBIaWdoLWNvbnRyYXN0IGNvbG9ycyAobWFudWFsbHkgZGVmaW5lZCkNCiAgYWNjZXNzaWJsZV9jb2xvcnMgPC0gYygNCiAgJyNENTVFMDAnLCAgIyBWZXJtaWxsaW9uDQogICcjMDA3MkIyJywgICMgQmx1ZQ0KICAnI0YwRTQ0MicsICAjIFllbGxvdw0KICAnIzAwOUU3MycsICAjIEdyZWVuDQogICcjNTZCNEU5JywgICMgU2t5IEJsdWUNCiAgJyNFNjlGMDAnLCAgIyBPcmFuZ2UNCiAgJyNDQzc5QTcnICAgIyBQaW5rDQogICkNCiAgZmlnIDwtIHBsb3RfbHkoZGYsIHggPSB+Y2F0ZWdvcnksIHkgPSB+dmFsdWVzLCB0eXBlID0gJ2JhcicsDQogICAgICAgICAgICAgICAgaG92ZXJpbmZvID0gJ3RleHQnLA0KICAgICAgICAgICAgICAgdGV4dCA9IH5wYXN0ZSgnQ2F0ZWdvcnk6JywgY2F0ZWdvcnksICc8YnI+VmFsdWU6JywgdmFsdWVzLCAnPGJyPlBlcmNlbnRhZ2U6Jywgcm91bmQodmFsdWVzL3N1bSh2YWx1ZXMpKjEwMCwgMSksICclJyksDQogICAgICAgICAgICAgICAjdGV4dCA9IH5wYXN0ZSgiVmFsdWU6IiwgdmFsdWVzKSwgDQogICAgICAgICAgICAgICB0ZXh0cG9zaXRpb24gPSAnYXV0bycsDQogICAgICAgICAgICAgICBtYXJrZXIgPSBsaXN0KA0KICAgICAgICAgICAgICAgICBjb2xvciA9IGFjY2Vzc2libGVfY29sb3JzWzE6bnJvdyhkZildLA0KICAgICAgICAgICAgICAgICBsaW5lID0gbGlzdChjb2xvciA9ICdibGFjaycsIHdpZHRoID0gMikNCiAgICAgICAgICAgICAgICksDQogICAgICAgICAgICAgICB0ZXh0Zm9udCA9IGxpc3QoY29sb3IgPSAnd2hpdGUnLCBzaXplID0gMTIpKSAlPiUNCiAgIGxheW91dCgNCiAgICMgdGl0bGUgPSBsaXN0KHRleHQgPSB2YXJuYW1lLCANCiAgICAgICAgICAgICAgICAjIGZvbnQgPSBsaXN0KHNpemUgPSAxOCwgY29sb3IgPSAnYmxhY2snKSksDQogICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gIkNhdGVnb3JpZXMiLCANCiAgICAgICAgICAgICAgICAgdGlja2ZvbnQgPSBsaXN0KGNvbG9yID0gJ2JsYWNrJykpLA0KICAgIHlheGlzID0gbGlzdCh0aXRsZSA9ICJWYWx1ZXMiLCANCiAgICAgICAgICAgICAgICAgZ3JpZGNvbG9yID0gJ2xpZ2h0Z3JheScsDQogICAgICAgICAgICAgICAgIHRpY2tmb250ID0gbGlzdChjb2xvciA9ICdibGFjaycpKSwNCiAgICBwbG90X2JnY29sb3IgPSAnd2hpdGUnLA0KICAgIHBhcGVyX2JnY29sb3IgPSAnd2hpdGUnLA0KICAgIHNob3dsZWdlbmQgPSBGQUxTRSwNCiAgICBtYXJnaW4gPSBsaXN0KA0KICAgICAgICAgICAgICAgICAgdCA9IDEwMCwgICMgQWRqdXN0IHRoaXMgdmFsdWUgdG8gaW5jcmVhc2Ugb3IgZGVjcmVhc2UgdGhlIHRvcCBtYXJnaW4NCiAgICAgICAgICAgICAgICAgIGIgPSA1MCwNCiAgICAgICAgICAgICAgICAgIGwgPSA1MCwNCiAgICAgICAgICAgICAgICAgIHIgPSA1MCkNCiAgKQ0KZmlnDQp9DQpgYGANCg0KDQoNCmBgYHtyfQ0KaW4uY2F0LnNleCA8LSAgZmluYWwuYW54aWV0eS5kYXQkc2V4DQppbi5jYXQucmFjZSA8LSAgZmluYWwuYW54aWV0eS5kYXQkcmFjZQ0KaW4uY2F0LmNsYXNzIDwtICBmaW5hbC5hbnhpZXR5LmRhdCRjbGFzcw0KaW4uY2F0Lm1ham9yIDwtICBmaW5hbC5hbnhpZXR5LmRhdCRtYWpvcg0KaW4uY2F0Lm1hdGgubGV2ZWwgPC0gIGZpbmFsLmFueGlldHkuZGF0JG1hdGgubGV2ZWwNCmluLmNhdC5tb2RhbGl0eSA8LSAgZmluYWwuYW54aWV0eS5kYXQkbW9kYWxpdHkNCiMjDQpnLnNleCA8LSBEZW1vZ3JhcGhpYy5iYXIoaW4uY2F0LnNleCwgIkdlbmRlciBEaXN0cmlidXRpb24iKQ0KZy5yYWNlIDwtIERlbW9ncmFwaGljLmJhcihpbi5jYXQucmFjZSwgIlJhY2lhbCBEaXN0cmlidXRpb24iKQ0KZy5jbGFzcyA8LSBEZW1vZ3JhcGhpYy5iYXIoaW4uY2F0LmNsYXNzLCAiQ2xhc3MgRGlzdHJpYnV0aW9uIikNCmcubWFqb3IgPC0gRGVtb2dyYXBoaWMuYmFyKGluLmNhdC5tYWpvciwgIk1ham9yIERpc3RyaWJ1dGlvbiIpDQpnLm1hdGgubGV2ZWwgPC0gRGVtb2dyYXBoaWMuYmFyKGluLmNhdC5tYXRoLmxldmVsLCAiTWF0aCBDb3Vyc2UgTGV2ZWwiKQ0KZy5tb2RhbGl0eSA8LSBEZW1vZ3JhcGhpYy5iYXIoaW4uY2F0Lm1vZGFsaXR5LCAiTGVhcm5pbmcgTW9kYWxpdHkiKQ0KYGBgDQoNCg0KDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9OH0NCiMgQXJyYW5nZSBpbiAyeDIgZ3JpZA0Kc3VicGxvdChnLnNleCwgZy5yYWNlLCBnLmNsYXNzLCBnLm1ham9yLCBucm93cyA9IDIsIHRpdGxlWCA9IEZBTFNFLCB0aXRsZVkgPSBUUlVFLCBtYXJnaW4gPSAwLjEpICU+JQ0KICBsYXlvdXQoDQogICAgYW5ub3RhdGlvbnMgPSBsaXN0KA0KICAgICAgbGlzdCh4ID0gMC4zNSwgeSA9IC45OSwgdGV4dCA9ICJHZW5kZXIiLCANCiAgICAgICAgICAgeHJlZiA9ICJwYXBlciIsIHlyZWYgPSAicGFwZXIiLCBzaG93YXJyb3cgPSBGQUxTRSwgZm9udCA9IGxpc3Qoc2l6ZSA9IDE0KSksDQogICAgICBsaXN0KHggPSAwLjc1LCB5ID0gMC45OSwgdGV4dCA9ICJSYWNlIiwgDQogICAgICAgICAgIHhyZWYgPSAicGFwZXIiLCB5cmVmID0gInBhcGVyIiwgc2hvd2Fycm93ID0gRkFMU0UsIGZvbnQgPSBsaXN0KHNpemUgPSAxNCkpLA0KICAgICAgbGlzdCh4ID0gMC4zNSwgeSA9IDAuNCwgdGV4dCA9ICJDbGFzcyBMZXZlbCIsIA0KICAgICAgICAgICB4cmVmID0gInBhcGVyIiwgeXJlZiA9ICJwYXBlciIsIHNob3dhcnJvdyA9IEZBTFNFLCBmb250ID0gbGlzdChzaXplID0gMTQpKSwNCiAgICAgIGxpc3QoeCA9IDAuNzUsIHkgPSAwLjQsIHRleHQgPSAiTWFqb3IiLCANCiAgICAgICAgICAgeHJlZiA9ICJwYXBlciIsIHlyZWYgPSAicGFwZXIiLCBzaG93YXJyb3cgPSBGQUxTRSwgZm9udCA9IGxpc3Qoc2l6ZSA9IDE0KSkNCiAgICApLA0KICAgIHNob3dsZWdlbmQgPSBGQUxTRQ0KICApDQpgYGANCg0KDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9NH0NCiMgQXJyYW5nZSBpbiAyeDIgZ3JpZA0Kc3VicGxvdChnLm1hdGgubGV2ZWwsIGcubW9kYWxpdHksIG5yb3dzID0gMSwgdGl0bGVYID0gRkFMU0UsIHRpdGxlWSA9IFRSVUUsIG1hcmdpbiA9IDAuMSkgJT4lDQogIGxheW91dCgNCiAgICBhbm5vdGF0aW9ucyA9IGxpc3QoDQogICAgICBsaXN0KHggPSAwLjM1LCB5ID0gLjk5LCB0ZXh0ID0gIk1hdGggQ291cnNlIExldmVsIiwgDQogICAgICAgICAgIHhyZWYgPSAicGFwZXIiLCB5cmVmID0gInBhcGVyIiwgc2hvd2Fycm93ID0gRkFMU0UsIGZvbnQgPSBsaXN0KHNpemUgPSAxNCkpLA0KICAgICAgbGlzdCh4ID0gMC43NSwgeSA9IDAuOTksIHRleHQgPSAiTGVhcm5pbmcgTW9kYWxpdHkiLCANCiAgICAgICAgICAgeHJlZiA9ICJwYXBlciIsIHlyZWYgPSAicGFwZXIiLCBzaG93YXJyb3cgPSBGQUxTRSwgZm9udCA9IGxpc3Qoc2l6ZSA9IDE0KSkNCiAgICApLA0KICAgIHNob3dsZWdlbmQgPSBGQUxTRQ0KICApDQpgYGANCg0KDQpPbmx5IG9uZSBjYXRlZ29yeSBpbiB2YXJpYWJsZSAqKmNsYXNzKiogaXMgbGVzcyB0aGFuIDMlIHdpdGggMjEgb2JzZXJ2YXRpb25zLiBPdGhlciB2YXJpYWJsZXMgZG9uJ3QgaGF2ZSBpc3N1ZXMgb24gc3BhcnNlIGNhdGVnb3JpZXMuDQoNCg0KDQojIyBSZWxhdGlvbnNoaXAgQmV0d2VlbiBNYXRoIEFueGlldHkgYW5kIERlbW9ncmFwaGljIEZhY3RvcnMNCg0KQSBzdHVkZW50J3MgZGVtb2dyYXBoaWMgcHJvZmlsZSBkb2Vzbid0IGRldGVybWluZSB0aGVpciBtYXRoIGFueGlldHksIGJ1dCBpdCBzaWduaWZpY2FudGx5IGluZmx1ZW5jZXMgd2hpY2ggdHlwZSBvZiBhbnhpZXR5IHRoZXkgYXJlIG1vc3QgdnVsbmVyYWJsZSB0byBhbmQgd2h5LiBUaGUgbmV4dCBzdWJzZWN0aW9ucyBwcmVzZW50IHZpc3VhbCBleHBsb3JhdGlvbnMgb2YgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGRlbW9ncmFwaGljIGZhY3RvcnMgYW5kIHRoZSB0d28gZGltZW5zaW9ucyBvZiBtYXRoZW1hdGljYWwgYW54aWV0eS4NCg0KIyMjIE1hdGhlbWF0aWNhbCBFdmFsdWF0aW9uIEFueGlldHkNCg0KVGhpcyBpcyB0aGUgYW54aWV0eSBhIHN0dWRlbnQgZmVlbHMgd2hlbiB0aGVpciBtYXRoZW1hdGljYWwgYWJpbGl0eSBpcyBiZWluZyBmb3JtYWxseSBvciBpbmZvcm1hbGx5IGFzc2Vzc2VkLiBUaGUgcHJpbWFyeSBmZWFyIGlzIG5vdCBvZiB0aGUgbWF0aCBpdHNlbGYsIGJ1dCBvZiB0aGUgbmVnYXRpdmUgY29uc2VxdWVuY2VzIG9mIHBlcmZvcm1pbmcgcG9vcmx5LiBJdCdzIHBlcmZvcm1hbmNlLW9yaWVudGVkLiBUaGUgc3RyZXNzIGNvbWVzIGZyb20gdGhlIHNpdHVhdGlvbiBvZiBiZWluZyBldmFsdWF0ZWQsIG5vdCBuZWNlc3NhcmlseSBmcm9tIHRoZSBjb250ZW50Lg0KDQoNCmBgYHtyfQ0KIyMgcGxvdGx5IGZvciBhbnhpZXR5IHZzIGdlbmRlciBhbmQgb3RoZXIgY2F0ZWdvcmljYWwgZGVtb2dyYXBoaWMgZmFjdG9yDQpnZW5kZXIucGxvdGx5IDwtIGZ1bmN0aW9uKGluLnZhcjEsIGluLnZhcjIpew0KICAgICAgZ2VuZGVyLmFueGlldHkgPC0gcGxvdF9seShmaW5hbC5hbnhpZXR5LmRhdCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ID0gfnNleCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gfkFueGlldHkubWVhLnd0LnBjYSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IGFzLmZvcm11bGEocGFzdGUwKCJ+Iixpbi52YXIxKSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlID0gImJveCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib3hwb2ludHMgPSAibm8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaml0dGVyID0gMC4zLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRwb3MgPSAwLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaG92ZXJpbmZvID0gInkgKyB4ICsgbmFtZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBob3ZlcnRleHQgPSB+cGFzdGUoIkdyb3VwOiIsIGluLnZhcjEsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGJyPkZhY3RvcjoiLCBzZXgsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGJyPlNjb3JlOiIsIHJvdW5kKEFueGlldHkubWVhLnd0LnBjYSwgMikpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFya2VyID0gbGlzdChzaXplID0gNSwgb3BhY2l0eSA9IDAuNykpICU+JQ0KICAgIGxheW91dCh0aXRsZSA9IHBhc3RlKCJNYXRoIEV2YWx1YXRpb24gQW54aWV0eSAod3QuUENBKTogR2VuZGVyIHZzICIsIGluLnZhcjIsIiIpLA0KICAgICAgICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gIiIpLA0KICAgICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIkV2YWx1YXRpb24gQW54aWV0eSBTY29yZSIpLA0KICAgICAgICAgYm94bW9kZSA9ICJncm91cCIsDQogICAgICAgICBob3ZlcmxhYmVsID0gbGlzdChiZ2NvbG9yID0gIndoaXRlIiwgZm9udCA9IGxpc3Qoc2l6ZSA9IDEyKSksDQogICAgICAgICBtYXJnaW4gPSBsaXN0KA0KICAgICAgICAgICAgICAgICAgdCA9IDEwMCwgICMgQWRqdXN0IHRoaXMgdmFsdWUgdG8gaW5jcmVhc2Ugb3IgZGVjcmVhc2UgdGhlIHRvcCBtYXJnaW4NCiAgICAgICAgICAgICAgICAgIGIgPSA1MCwNCiAgICAgICAgICAgICAgICAgIGwgPSA1MCwNCiAgICAgICAgICAgICAgICAgIHIgPSA1MCkNCiAgICAgICAgICkNCg0KIGdlbmRlci5hbnhpZXR5IA0KfQ0KDQpgYGANCg0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTR9DQpnZW5kZXIubWF0aC5sZXZlbCA9IGdlbmRlci5wbG90bHkoIm1hdGgubGV2ZWwiLCAiTWF0aCBDb3Vyc2UgTGV2ZWwiKQ0KZ2VuZGVyLm1hdGgubGV2ZWwNCmBgYA0KDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9NH0NCmdlbmRlci5yYWNlID0gZ2VuZGVyLnBsb3RseSgicmFjZSIsICJSYWNlIikNCmdlbmRlci5yYWNlDQpgYGANCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00fQ0KZ2VuZGVyLmNsYXNzID0gZ2VuZGVyLnBsb3RseSgiY2xhc3MiLCAiQ2xhc3MiKQ0KZ2VuZGVyLmNsYXNzDQpgYGANCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00fQ0KZ2VuZGVyLm1ham9yID0gZ2VuZGVyLnBsb3RseSgibWFqb3IiLCAiTWFqb3IiKQ0KZ2VuZGVyLm1ham9yDQpgYGANCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00fQ0KZ2VuZGVyLm1vZGFsaXR5ID0gZ2VuZGVyLnBsb3RseSgibW9kYWxpdHkiLCAiTW9kYWxpdHkiKQ0KZ2VuZGVyLm1vZGFsaXR5DQpgYGANCg0KDQoNClNvbWUgb2YgdGhlIHBhdHRlcm5zIG9ic2VydmVkIGluIHRoaXMgc3R1ZHkgYXJlIGNvbnNpc3RlbnQgd2l0aCB0aGUgZXhpc3RpbmcgbGl0ZXJhdHVyZS4NCg0KKiBGZW1hbGUgc3R1ZGVudHMgaGF2ZSByZWxhdGl2ZWx5IGhpZ2hlciBldmFsdWF0aW9uIGFueGlldHkgbGV2ZWwgdGhhbiBtYWxlIHN0dWRlbnRzLg0KKiBUaGUgZGlzY3JlcGFuY3kgb2YgZXZhbHVhdGlvbiBhbnhpZXR5IGxldmVsIGFjcm9zcyBldGhuaWMgZ3JvdXBzIGFsc28gY29uc2lzdGVudCB3aXRoIHdoYXQgcmVwb3J0ZWQgaW4gdGhlIGV4aXN0aW5nIGxpdGVyYXR1cmUuDQoNCg0KIyMjIE1hdGhlbWF0aWNhbCBMZWFybmluZyBBbnhpZXR5DQoNCk1hdGhlbWF0aWNhbCBsZWFybmluZyBhbnhpZXR5IHN0ZW1zIGRpcmVjdGx5IGZyb20gdGhlIHN1YmplY3QgbWF0dGVyLCB3aGVyZSB0aGUgcHJpbWFyeSBzb3VyY2Ugb2YgZGlzdHJlc3MgaXMgdGhlIGFjdCBvZiBlbmdhZ2luZyB3aXRoIG1hdGhlbWF0aWNhbCBjb25jZXB0cy4gVGhpcyBlbmdhZ2VtZW50IHRyaWdnZXJzIGFuIGludGVybmFsIHN0YXRlIG9mIGNvbmZ1c2lvbiwgZnJ1c3RyYXRpb24sIGFuZCBjb2duaXRpdmUgb3ZlcmxvYWQuDQoNClRoZSBuZXh0IGZldyBmaWd1cmVzIGV4YW1pbmUgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIG1hdGhlbWF0aWNhbCBsZWFybmluZyBhbnhpZXR5IGFuZCBkZW1vZ3JhcGhpYyBmYWN0b3JzLCB1c2luZyB0aGUgc2FtZSB2aXN1YWwgYXBwcm9hY2ggYXMgd2UgZGlkIGZvciBtYXRoZW1hdGljYWwgZXZhbHVhdGlvbiBhbnhpZXR5Lg0KDQoNCmBgYHtyfQ0KIyMgcGxvdGx5IGZvciBhbnhpZXR5IHZzIGdlbmRlciBhbmQgb3RoZXIgY2F0ZWdvcmljYWwgZGVtb2dyYXBoaWMgZmFjdG9yDQpnZW5kZXIucGxvdGx5IDwtIGZ1bmN0aW9uKGluLnZhcjEsIGluLnZhcjIpew0KICAgICAgZ2VuZGVyLmFueGlldHkgPC0gcGxvdF9seShmaW5hbC5hbnhpZXR5LmRhdCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ID0gfnNleCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gfkFueGlldHkubWxhLnd0LnBjYSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IGFzLmZvcm11bGEocGFzdGUwKCJ+Iixpbi52YXIxKSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlID0gImJveCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib3hwb2ludHMgPSAibm8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaml0dGVyID0gMC4zLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRwb3MgPSAwLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaG92ZXJpbmZvID0gInkgKyB4ICsgbmFtZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBob3ZlcnRleHQgPSB+cGFzdGUoIkdyb3VwOiIsIGluLnZhcjEsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGJyPkZhY3RvcjoiLCBzZXgsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGJyPlNjb3JlOiIsIHJvdW5kKEFueGlldHkubWxhLnd0LnBjYSwgMikpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFya2VyID0gbGlzdChzaXplID0gNSwgb3BhY2l0eSA9IDAuNykpICU+JQ0KICAgIGxheW91dCh0aXRsZSA9IHBhc3RlKCJNYXRoIExlYXJuaW5nIEFueGlldHkgKHd0LlBDQSk6IEdlbmRlciB2cyAiLCBpbi52YXIyLCIiKSwNCiAgICAgICAgIHhheGlzID0gbGlzdCh0aXRsZSA9ICIiKSwNCiAgICAgICAgIHlheGlzID0gbGlzdCh0aXRsZSA9ICJMZWFybmluZyBBbnhpZXR5IFNjb3JlIiksDQogICAgICAgICBib3htb2RlID0gImdyb3VwIiwNCiAgICAgICAgIGhvdmVybGFiZWwgPSBsaXN0KGJnY29sb3IgPSAid2hpdGUiLCBmb250ID0gbGlzdChzaXplID0gMTIpKSwNCiAgICAgICAgIG1hcmdpbiA9IGxpc3QoDQogICAgICAgICAgICAgICAgICB0ID0gMTAwLCAgIyBBZGp1c3QgdGhpcyB2YWx1ZSB0byBpbmNyZWFzZSBvciBkZWNyZWFzZSB0aGUgdG9wIG1hcmdpbg0KICAgICAgICAgICAgICAgICAgYiA9IDUwLA0KICAgICAgICAgICAgICAgICAgbCA9IDUwLA0KICAgICAgICAgICAgICAgICAgciA9IDUwKQ0KICAgICAgICAgKQ0KDQogZ2VuZGVyLmFueGlldHkgDQp9DQoNCmBgYA0KDQoNCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00fQ0KZ2VuZGVyLm1hdGgubGV2ZWwubWxhID0gZ2VuZGVyLnBsb3RseSgibWF0aC5sZXZlbCIsICJNYXRoIENvdXJzZSBMZXZlbCIpDQpnZW5kZXIubWF0aC5sZXZlbC5tbGENCmBgYA0KDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9NH0NCmdlbmRlci5yYWNlLm1sYSA9IGdlbmRlci5wbG90bHkoInJhY2UiLCAiUmFjZSIpDQpnZW5kZXIucmFjZS5tbGENCmBgYA0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTR9DQpnZW5kZXIuY2xhc3MubWxhID0gZ2VuZGVyLnBsb3RseSgiY2xhc3MiLCAiQ2xhc3MiKQ0KZ2VuZGVyLmNsYXNzLm1sYQ0KYGBgDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9NH0NCmdlbmRlci5tYWpvci5tbGEgPSBnZW5kZXIucGxvdGx5KCJtYWpvciIsICJNYWpvciIpDQpnZW5kZXIubWFqb3IubWxhDQpgYGANCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00fQ0KZ2VuZGVyLm1vZGFsaXR5Lm1sYSA9IGdlbmRlci5wbG90bHkoIm1vZGFsaXR5IiwgIk1vZGFsaXR5IikNCmdlbmRlci5tb2RhbGl0eS5tbGENCmBgYA0KDQoNCiMjIFRoZSBHZW5kZXIgR2FwIGluIEV2YWx1YXRpb24gYW5kIExlYXJuaW5nIEFueGlldHkNCg0KSXQgdHVybnMgb3V0IHRoYXQsIGNvbXBhcmluZyB0byBtYXRoIGxlYXJuaW5nIGFueGlldHksIGV2YWx1YXRpb24gYW54aWV0eSBtYW5pZmVzdHMgdGhlIGdlbmRlciBnYXAuIFRoaXMgb2JzZXJ2YXRpb24gaXMgc3VwcG9ydGVkIGJ5IGFjYWRlbWljIHJlc2VhcmNoLiBUaGUga2V5IGluc2lnaHQgaXMgdGhhdCB0aGUgZ2VuZGVyIGdhcCBpbiBtYXRoIHBlcmZvcm1hbmNlIGlzIG1vcmUgc3Ryb25nbHkgbGlua2VkIHRvIHRoZSBhbnhpZXR5IGdlbmVyYXRlZCBieSB0aGUgdGVzdGluZyBzaXR1YXRpb24gdGhhbiBieSBhbnhpZXR5IHRvd2FyZCB0aGUgc3ViamVjdCBtYXR0ZXIgaXRzZWxmIChsZWFkaW5nIHBvdGVudGlhbCBsZWFybmluZyBhbnhpZXR5KS4NCg0KQSByb2J1c3QgYm9keSBvZiBldmlkZW5jZSwgZnJvbSBmb3VuZGF0aW9uYWwgbWV0YS1hbmFseXNlcyAoSGVtYnJlZSwgMTk5MCkgdG8gY29udGVtcG9yYXJ5IHN0dWRpZXMgKERldmluZSBldCBhbC4sIDIwMTI7IEdvZXR6IGV0IGFsLiwgMjAxMyksIGVzdGFibGlzaGVzIHRoYXQgZmVtYWxlIHN0dWRlbnRzIGV4cGVyaWVuY2UgZGlzcHJvcG9ydGlvbmF0ZWx5IGhpZ2ggbGV2ZWxzIG9mIG1hdGggdGVzdCBhbnhpZXR54oCUYSBmYWN0b3IgbW9yZSBwcmVkaWN0aXZlIG9mIGFjYWRlbWljIG91dGNvbWVzIHRoYW4gbGVhcm5pbmcgYW54aWV0eS4gVGhpcyBmaW5kaW5nIGlsbHVtaW5hdGVzIHRoZSB3b3JrIG9mIEVsc2UtUXVlc3QgZXQgYWwuICgyMDEwKSwgZGVtb25zdHJhdGluZyB0aGF0IHRoZSBnZW5kZXIgZ2FwIGluIG1hdGggcGVyZm9ybWFuY2UgaXMgcHJvZm91bmRseSBzaGFwZWQgYnkgYW54aWV0eSBpbiBldmFsdWF0aXZlIGVudmlyb25tZW50cy4gVGhlcmVmb3JlLCBhZGRyZXNzaW5nIHRoZSBzcGVjaWZpYyBwcmVzc3VyZXMgb2YgdGVzdGluZyBzaXR1YXRpb25zIGlzIGVzc2VudGlhbCBmb3IgY2xvc2luZyB0aGlzIGdhcC4NCg0KVGhlIGZvbGxvd2luZyBmaWd1cmUgaWxsdXN0cmF0ZXMgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGdlbmRlciBhbmQgdGhlIHR3byB0eXBlcyBvZiBtYXRoIGFueGlldHk6IGxlYXJuaW5nIGFueGlldHkgYW5kIGV2YWx1YXRpb24gYW54aWV0eS4NCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD02fQ0KbWVhMCA8LSBmaW5hbC5hbnhpZXR5LmRhdFssIGMoInNleCIsICJBbnhpZXR5Lm1lYS53dC5wY2EiKV0NCm1sYTAgPC0gZmluYWwuYW54aWV0eS5kYXRbLCBjKCJzZXgiLCAiQW54aWV0eS5tbGEud3QucGNhIildDQpuYW1lcyhtZWEwKSA9IGMoInNleCIsICJhbnhpZXR5LnNjb3JlIikNCm5hbWVzKG1sYTApID0gYygic2V4IiwgImFueGlldHkuc2NvcmUiKQ0KbWVhLm1sYSA8LSByYmluZChtZWEwLCBtbGEwKQ0KYW54aWV0eS50eXBlIDwtIGMocmVwKCJtZWEiLCBkaW0obWVhMClbMV0pLCByZXAoIm1sYSIsIGRpbShtZWEwKVsxXSkpDQptZWEubWxhJGFueGlldHkudHlwZSA8LSBhbnhpZXR5LnR5cGUNCiMjIyMNCmRmID0gbmEub21pdChtZWEubWxhKQ0KIyBDcmVhdGUgbW9yZSBjb21wbGV4IGdyb3VwZWQgYm94cGxvdCB3aXRoIHN0YXRpc3RpY2FsIGFubm90YXRpb25zDQojIEN1c3RvbSBob3ZlciBpbmZvcm1hdGlvbg0KZmlnIDwtIHBsb3RfbHkoZGYsIA0KICAgICAgICAgICAgICAgeCA9IH5hbnhpZXR5LnR5cGUsIA0KICAgICAgICAgICAgICAgeSA9IH5hbnhpZXR5LnNjb3JlLCANCiAgICAgICAgICAgICAgIGNvbG9yID0gfnNleCwNCiAgICAgICAgICAgICAgIHR5cGUgPSAiYm94IiwNCiAgICAgICAgICAgICAgIGhvdmVyaW5mbyA9ICJ5K3grbmFtZSIsDQogICAgICAgICAgICAgICBob3ZlcnRlbXBsYXRlID0gcGFzdGUoDQogICAgICAgICAgICAgICAgICJHZW5kZXI6ICV7eH08YnI+IiwNCiAgICAgICAgICAgICAgICAgIkFueGlldHkgVHlwZTogJXtmdWxsRGF0YS5uYW1lfTxicj4iLA0KICAgICAgICAgICAgICAgICAiQW54aWV0eSBTY29yZTogJXt5Oi4yZn08YnI+IiwNCiAgICAgICAgICAgICAgICAgIjxleHRyYT48L2V4dHJhPiINCiAgICAgICAgICAgICAgICkpICU+JQ0KICBsYXlvdXQoDQogICAgdGl0bGUgPSAiR2VuZGVyIERpc3Bhcml0aWVzIGluIE1hdGggRXZhbHVhdGlvbiBhbmQgTGVhcm5pbmcgQW54aWV0eSIsDQogICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gIiIpLA0KICAgIHlheGlzID0gbGlzdCh0aXRsZSA9ICJBbnhpZXR5IFNjb3JlIiksDQogICAgYm94bW9kZSA9ICJncm91cCIsDQogICAgaG92ZXJsYWJlbCA9IGxpc3QoYmdjb2xvciA9ICJ3aGl0ZSIsIGZvbnQgPSBsaXN0KHNpemUgPSAxMikpLA0KICAgIG1hcmdpbiA9IGxpc3QoIHQgPSAxMDAsICAjIEFkanVzdCB0aGlzIHZhbHVlIHRvIGluY3JlYXNlIG9yIGRlY3JlYXNlIHRoZSB0b3AgbWFyZ2luDQogICAgICAgICAgICAgICAgICBiID0gNTAsDQogICAgICAgICAgICAgICAgICBsID0gNTAsDQogICAgICAgICAgICAgICAgICByID0gNTApDQogICkNCg0KZmlnDQoNCmBgYA0KDQpPdXIgcmVzdWx0cyBhcmUgYWxzbyBjb25zaXN0ZW50IHdpdGggZXhpc3RpbmcgcmVzdWx0cyBpbiBsaXRlcmF0dXJlLg0KDQoNCiMgU3R1ZGVudCBQZXJjZWl2ZWQgVGVhY2hpbmcgU3RyYXRlZ2llcyBhbmQgTWF0aCBBbnhpZXR5DQoNCk1hdGggYW54aWV0eSBpcyBvZnRlbiBleGFjZXJiYXRlZCBieSBhIGRpc2Nvbm5lY3QgYmV0d2VlbiBhIHN0dWRlbnQncyBjb2duaXRpdmUgbmVlZHMgYW5kIHRoZSBpbnN0cnVjdG9yJ3MgcHJlZG9taW5hbnQgcGVkYWdvZ2ljYWwgYXBwcm9hY2guIFRvIG1pdGlnYXRlIHRoaXMsIGEgcHJvYWN0aXZlIG1ldGhvZCBpbnZvbHZlcyBsZXZlcmFnaW5nIHN0dWRlbnRzJyBwZXJjZXB0aW9ucyBvZiB0ZWFjaGluZyBzdHJhdGVnaWVzLiANCg0KIyMgSGVhdG1hcCBvZiBQYWlyd2lzZSBDb3JyZWxhdGlvbnMNCg0KVGhlIGZvbGxvd2luZyBoZWF0bWFwIGlsbHVzdHJhdGVzIHRoZSBwYWlyd2lzZSBjb3JyZWxhdGlvbnMgYmV0d2VlbiBhbnhpZXR5IGxldmVscywgc3R1ZGVudC1wZXJjZWl2ZWQgdGVhY2hpbmcgc3RyYXRlZ2llcywgYW5kIG90aGVyIGFzc29jaWF0ZWQgY29nbml0aXZlIGZhY3RvcnMuIEEgbmVnYXRpdmUgY29ycmVsYXRpb24gYmV0d2VlbiBhbnhpZXR5IGFuZCBhbm90aGVyIGNvbXBvc2l0ZSBzY29yZSAoc2hvd24gaW4gYmx1ZSkgaW5kaWNhdGVzIHRoYXQgYW54aWV0eSBkZWNyZWFzZXMgYXMgdGhhdCBjb21wb3NpdGUgc2NvcmUgaW5jcmVhc2VzLg0KDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9Nn0NCg0KdmFyLm5hbWUgPC1jKCAiQW54aWV0eS5tZWEud3QucGNhIiwgIkFueGlldHkubWxhLnd0LnBjYSIsICJTZWxmRWZmaWNhY3kud3QucGNhIiwgIlRlY2hub2xvZ3kud3QucGNhIiwNCiAgICAgICAgICAgICAgIkNvb3BvcmF0aXZlLnd0LnBjYSIsICJEZWR1Y3RpdmUud3QucGNhIiwgIkRlbW9uc3RyYXRpb24ud3QucGNhIiwNCiAgICAgICAgICAgICAgIkluZHVjdGl2ZS53dC5wY2EiLCAiSW50ZWdyYXRpdmUud3QucGNhIiwgIkxlY3R1cmVUeXBlLnd0LnBjYSIsDQogICAgICAgICAgICAgICJSZXBldGl0aXZlLnd0LnBjYSIsICJFbmdhZ2Uud3QucGNhIiwgIlJlc291cmNlLnd0LnBjYSIpDQphbGwuY29tcG9zaXRlLnNjb3JlcyA8LSBmaW5hbC5hbnhpZXR5LmRhdFssIHZhci5uYW1lXQ0KbmFtZXMoYWxsLmNvbXBvc2l0ZS5zY29yZXMpIDwtIGMoICJBbnhpZXR5Lm1lYSIsICJBbnhpZXR5Lm1sYSIsICJTZWxmRWZmaWNhY3kiLCAiVGVjaG5vbG9neSIsDQogICAgICAgICAgICAgICJDb29wb3JhdGl2ZSIsICJEZWR1Y3RpdmUuIiwgIkRlbW9uc3RyYXRpb24iLA0KICAgICAgICAgICAgICAiSW5kdWN0aXZlIiwgIkludGVncmF0aXZlIiwgIkxlY3R1cmVUeXBlIiwNCiAgICAgICAgICAgICAgIlJlcGV0aXRpdmUiLCAiRW5nYWdlIiwgIlJlc291cmNlLiIpDQoNCiMgQ2FsY3VsYXRlIGNvcnJlbGF0aW9uIG1hdHJpeA0KY29yX21hdHJpeCA8LSBjb3IoYWxsLmNvbXBvc2l0ZS5zY29yZXMsIHVzZSA9ICJjb21wbGV0ZS5vYnMiKQ0KDQojIENvbnZlcnQgdG8gbG9uZyBmb3JtYXQgdXNpbmcgbWVsdA0KY29yX2xvbmcgPC0gbWVsdChjb3JfbWF0cml4KQ0KbmFtZXMoY29yX2xvbmcpIDwtIGMoIngiLCAieSIsICJyIikNCg0KIyBSZW1vdmUgc2VsZi1jb3JyZWxhdGlvbnMgYW5kIHVwcGVyIHRyaWFuZ2xlIGlmIGRlc2lyZWQNCmNvcl9sb25nIDwtIGNvcl9sb25nW2Nvcl9sb25nJHggIT0gY29yX2xvbmckeSwgXQ0KDQojIENyZWF0ZSBpbnRlcmFjdGl2ZSBoZWF0bWFwDQpwbG90X2x5KGNvcl9sb25nLCB4ID0gfngsIHkgPSB+eSwgeiA9IH5yLCB0eXBlID0gImhlYXRtYXAiLA0KICAgICAgICBjb2xvcnNjYWxlID0gIlJkQnUiLCB6bWluID0gLTEsIHptYXggPSAxLA0KICAgICAgICBob3ZlcmluZm8gPSAidGV4dCIsDQogICAgICAgIHRleHQgPSB+cGFzdGUoIlg6IiwgeCwgIjxicj5ZOiIsIHksICI8YnI+ciA9Iiwgcm91bmQociwgMykpKSAlPiUNCiAgbGF5b3V0KHRpdGxlID0gIkNvcnJlbGF0aW9uIE1hdHJpeCIsDQogICAgICAgICB4YXhpcyA9IGxpc3QodGl0bGUgPSAiIiksDQogICAgICAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAiIiksDQogICAgICAgICBtYXJnaW4gPSBsaXN0KGwgPSAxMDAsIHIgPSA1MCwgYiA9IDEwMCwgdCA9IDUwKSkNCmBgYA0KDQpUaGUgZmlndXJlIGFib3ZlIHNob3dzIHRoYXQgYWxsIHBlcmNlaXZlZCB0ZWFjaGluZyBzdHJhdGVnaWVzIGFyZSBuZWdhdGl2ZWx5IGNvcnJlbGF0ZWQgd2l0aCBib3RoIHR5cGVzIG9mIGFueGlldHkuIEluIGFkZGl0aW9uLCBzdHVkZW50cyB3aXRoIGhpZ2ggbGV2ZWxzIG9mIHNlbGYtZWZmaWNhY3kgdGVuZCB0byBoYXZlIGxvdyBsZXZlbHMgb2YgbWF0aCBhbnhpZXR5LiBGdXJ0aGVybW9yZSwgdGhlIGNvbXBvc2l0ZSBzY29yZSBmb3IgdGVjaG5vbG9neSB1c2UgaXMgbmVnYXRpdmVseSBjb3JyZWxhdGVkIHdpdGggYm90aCBsZWFybmluZyBhbmQgZXZhbHVhdGlvbiBhbnhpZXR5LCBpbXBseWluZyB0aGF0IHRlY2hub2xvZ3kgY2FuIGhlbHAgcmVkdWNlIG1hdGggYW54aWV0eS4gQ29udmVyc2VseSwgd2UgYWxzbyBzZWUgdGhhdCBzdHVkZW50cyB3aG8gdXNlIG1vcmUgbGVhcm5pbmcgcmVzb3VyY2VzIHRlbmQgdG8gaGF2ZSBoaWdoZXIgbGVhcm5pbmcgYW54aWV0eS4NCg0KDQpBcyB0aGUgcmVkIGJsb2NrIGluIHRoZSBjZW50ZXIgb2YgdGhlIGhlYXRtYXAgaW5kaWNhdGVzLCBhbGwgdGVhY2hpbmcgc3RyYXRlZ2llcyBhcmUgcG9zaXRpdmVseSBjb3JyZWxhdGVkLiBUaGlzIGNvbGxpbmVhcml0eSBtYXkgcG9zZSBhIHByb2JsZW0gZm9yIHN1YnNlcXVlbnQgcmVncmVzc2lvbiBhbmFseXNpcy4gV2Ugd2lsbCBhZGRyZXNzIHRoaXMgY29uY2VybiBpbiB0aGUgZm9sbG93aW5nIHNlY3Rpb24uDQoNCg0KIyMgR3JvdXBpbmcgVGVhY2hpbmcgU3RyYXRlZ2llcw0KDQoNClRoZSBmb2xsb3dpbmcgZGVuc2l0eSBjdXJ2ZXMgcmVwcmVzZW50ICpuYWl2ZSogY29tcG9zaXRlIHNjb3JlcyBkZXJpdmVkIGZyb20gdGhlIGF2ZXJhZ2Ugb2YgaXRlbSBzY29yZXMgZm9yIGVhY2ggb2YgdGhlIHNldmVuIHRlYWNoaW5nIHN0cmF0ZWdpZXMuIFRoZXNlIGN1cnZlcyBpbGx1c3RyYXRlIHRoZSBzdHVkZW50cycgcGVyY2VwdGlvbnMgb2YgdGhlaXIgaW5zdHJ1Y3RvcnMnIHRlYWNoaW5nIHN0cmF0ZWdpZXMuIEEgaGlnaGVyIHNjb3JlIGluZGljYXRlcyB0aGF0IHN0dWRlbnRzIHdlcmUgbW9yZSBsaWtlbHkgdG8gcGVyY2VpdmUgdGhlIHVzZSBvZiB0aGF0IHN0cmF0ZWd5Lg0KDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9Niwgd2FybmluZyA9IEZBTFNFfQ0KdmFyLm5hbWUgPC1jKCAiQ29vcG9yYXRpdmUuYXZnIiwgIkRlZHVjdGl2ZS5hdmciLCAiRGVtb25zdHJhdGlvbi5hdmciLA0KICAgICAgICAgICAgICAiSW5kdWN0aXZlLmF2ZyIsICJJbnRlZ3JhdGl2ZS5hdmciLCAiTGVjdHVyZVR5cGUuYXZnIiwNCiAgICAgICAgICAgICAgIlJlcGV0aXRpdmUuYXZnIikNCmFsbC5jb21wb3NpdGUuc2NvcmVzIDwtIGZpbmFsLmFueGlldHkuZGF0WywgdmFyLm5hbWVdDQpuYW1lcyhhbGwuY29tcG9zaXRlLnNjb3JlcykgPC0gYygiQ29vcGVyYXRpdmUiLCAiRGVkdWN0aXZlIiwgIkRlbW9uc3RyYXRpdmUiLA0KICAgICAgICAgICAgICAiSW5kdWN0aXZlIiwgIkludGVncmF0aXZlIiwgIkxlY3R1cmUiLCAgICJSZXBldGl0aXZlIikNCg0KIyBGb3Igb2xkZXIgdmVyc2lvbnMgb2YgdGlkeXINCmxvbmdfZGF0YSA8LSBhbGwuY29tcG9zaXRlLnNjb3JlcyAlPiUNCiAgcGl2b3RfbG9uZ2VyKA0KICAgIGNvbHMgPSBjKCBDb29wZXJhdGl2ZSwgRGVkdWN0aXZlLCBEZW1vbnN0cmF0aXZlLCBJbmR1Y3RpdmUsIEludGVncmF0aXZlLCBMZWN0dXJlLCBSZXBldGl0aXZlKSwgICMgQ29sdW1ucyB0byByZXNoYXBlDQogICAgbmFtZXNfdG8gPSAidmFyaWFibGUiLCAgICAgICAgICAjIE5ldyBjb2x1bW4gbmFtZSBmb3IgdmFyaWFibGUgbmFtZXMNCiAgICB2YWx1ZXNfdG8gPSAidmFsdWUiICAgICAgICAgICAgICMgTmV3IGNvbHVtbiBuYW1lIGZvciB2YWx1ZXMNCiAgKQ0KDQojIyBTdW1tYXJpemVkIHN0YXRzDQoNCnN1bW1hcnlfc3RhdHMgPC0gbG9uZ19kYXRhICU+JQ0KICBncm91cF9ieSh2YXJpYWJsZSkgJT4lDQogIHN1bW1hcmlzZSgNCiAgICBtZWFuX3ZhbCA9IG1lYW4odmFsdWUpLA0KICAgIG1lZGlhbl92YWwgPSBtZWRpYW4odmFsdWUpLA0KICAgIHNkX3ZhbCA9IHNkKHZhbHVlKSwNCiAgICBuID0gbigpLA0KICAgIC5ncm91cHMgPSAnZHJvcCcNCiAgKQ0KDQojIENyZWF0ZSByaWRnZSBwbG90IHdpdGggZ2dyaWRnZXMgYW5kIGNvbnZlcnQgdG8gcGxvdGx5DQpyaWRnZV9nZyA8LSBnZ3Bsb3QobG9uZ19kYXRhLCBhZXMoeCA9IHZhbHVlLCB5ID0gdmFyaWFibGUsIGZpbGwgPSB2YXJpYWJsZQ0KICApKSArDQogIGdlb21fZGVuc2l0eV9yaWRnZXMoDQogICAgYWxwaGEgPSAwLjcsDQogICAgc2NhbGUgPSAyLCAgIyBBZGp1c3Qgb3ZlcmxhcA0KICAgIGNvbG9yID0gIndoaXRlIiwNCiAgICBzaXplID0gMC41LA0KICAgICApICsNCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJTZXQxIikgKw0KICAjdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDApKSArDQogIHRoZW1lX3JpZGdlcygpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJEaXN0cmlidXRpb25zIG9mIFN0dWRlbnRzJyBQZXJjZWl2ZWQgXG4gVGVhY2hpbmcgU3RyYXRlZ3kgSW5kaWNlcyIsDQogICAgeCA9ICJQZXJjZWl2ZWQgVGVhY2hpbmcgU3RyYXRlZ3kgU2NvcmUiLA0KICAgIHkgPSAiIg0KICApICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwNCiAgICAgICAgcGxvdC5tYXJnaW4gPSBtYXJnaW4odCA9IDEuMiwgdW5pdCA9ICJjbSIpKQ0KDQojIENvbnZlcnQgdG8gcGxvdGx5DQpnZ3Bsb3RseShyaWRnZV9nZykNCmBgYA0KDQoNCkFzIHNob3duIGluIHRoZSBmaWd1cmUsIHRoZSAqKnJlcGV0aXRpdmUqKiwgKipsZWN0dXJlLXR5cGUqKiwgKippbmR1Y3RpdmUqKiwgYW5kICoqZGVtb25zdHJhdGl2ZSoqIGFwcHJvYWNoZXMgd2VyZSBwZXJjZWl2ZWQgYXMgbW9yZSBwb3B1bGFyIHRoYW4gdGhlICoqaW50ZWdyYXRpdmUqKiwgKipkZWR1Y3RpdmUqKiwgYW5kICoqY29vcGVyYXRpdmUqKiBhcHByb2FjaGVzLiBUaGlzIG9ic2VydmF0aW9uIGFsaWducyB3aXRoIHRoZSBlc3RhYmxpc2hlZCBjbGFzc2lmaWNhdGlvbiBvZiB0ZWFjaGluZyBzdHlsZXMgaW4gZWR1Y2F0aW9uYWwgYW5kIHBzeWNob2xvZ2ljYWwgcmVzZWFyY2ggYW5kIGNsYXNzaWMgdGV4dGJvb2tzLg0KDQoNCnwgICAgVGVhY2hlci1jZW50ZXJlZCB8ICAgU3R1ZGVudC1jZW50ZXJlZCB8DQp8Oi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXw6LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18DQp8ICoqRGVkdWN0aXZlKiogKFRlYWNoZXIgcHJvdmlkZXMgcnVsZXMgYW5kIGV4YW1wbGVzOiBKb3ljZSBldCBhbC4sIDIwMTUpIHwJKipDb29wZXJhdGl2ZSoqIChTdHVkZW50cyB3b3JrIHRvZ2V0aGVyOiBKb2huc29uLCAyMDE0KXwNCnwgKipMZWN0dXJlIFR5cGUqKiAoVGVhY2hlciB0cmFuc21pdHMgaW5mb3JtYXRpb246IEJyb3duLDIwMDcpIHwJCSoqSW5kdWN0aXZlKiogKFN0dWRlbnRzIGRpc2NvdmVyIHJ1bGVzOiBCcnVuZXIsIDE5NjE7IFByaW5jZSAgJiBGZWxkZXIsIDIwMDYpfA0KfCAqKkRlbW9uc3RyYXRpb24qKiAoVGVhY2hlciBzaG93cyBob3c6IEJvcmljaCwgMjAxNykgfAkJKipJbnRlZ3JhdGl2ZSoqIChTdHVkZW50cyBjb25uZWN0IGlkZWFzOiBKYWNvYnMsIDE5ODk7IEZvZ2FydHksMTk5MSl8DQp8ICoqUmVwZXRpdGl2ZSoqIChUZWFjaGVyIGRyaWxscyB0aGUgaW5mb3JtYXRpb246IE9ybXJvZCwgMjAyMCkgfAkgIHwNCg0KVGhlIGFib3ZlIGNsYXNzaWZpY2F0aW9uIGlzIGNvbnNpc3RlbnQgd2l0aCB0aGUgb25lIGJhc2VkIG9uIGNvZ25pdGl2ZSBkZW1hbmQgKEJsb29tJ3MgVGF4b25vbXkpLCB3aGljaCBjYXRlZ29yaXplcyBzdHJhdGVnaWVzIGFzIHJlcXVpcmluZyBlaXRoZXIgbG93ZXItbGV2ZWwgdGhpbmtpbmcgKHJlbWVtYmVyLCB1bmRlcnN0YW5kKSBvciBoaWdoZXItbGV2ZWwgdGhpbmtpbmcgKGFwcGx5LCBhbmFseXplLCBldmFsdWF0ZSwgY3JlYXRlKS4gVA0KDQoNClRoaXMgY2xhc3NpZmljYXRpb24gZGVtb25zdHJhdGVzIGEgc3BlY3RydW0gb2YgcGVkYWdvZ2ljYWwgYXBwcm9hY2hlcywgZnJvbSB0cmFkaXRpb25hbCwgaGlnaGx5IHN0cnVjdHVyZWQgbWV0aG9kcyBsaWtlIExlY3R1cmUgYW5kIERlZHVjdGl2ZSB0ZWFjaGluZywgdG8gbW9kZXJuLCBzdHVkZW50LWRyaXZlbiBtZXRob2RzIGxpa2UgSW5kdWN0aXZlLCBDb29wZXJhdGl2ZSwgYW5kIEludGVncmF0aXZlIGxlYXJuaW5nLiBEZW1vbnN0cmF0aW9uIGFuZCBSZXBldGl0aXZlIHByYWN0aWNlIHNlcnZlIHNwZWNpZmljLCBvZnRlbiBjb21wbGVtZW50YXJ5LCByb2xlcyB3aXRoaW4gdGhpcyBzcGVjdHJ1bS4NCg0KDQojIyBDcmVhdGUgU2luZ2xlIENvbXBvc2l0ZSBTY29yZSBmb3IgdGhlIENsYXNzaWZpY2F0aW9uDQoNCldlIG5leHQgZGVmaW5lIHR3byBzaW5nbGUgaW5kaWNlcyB0byByZXByZXNlbnQgdGhlIHRlYWNoaW5nIHN0cmF0ZWdpZXMgYmFzZWQgb24gdGhlIGFib3ZlIGNsYXNzaWZpY2F0aW9uLiBXZSBjb25jZXB0dWFsaXplIHRlYWNoZXItY2VudGVyZWQgYW5kIHN0dWRlbnQtY2VudGVyZWQgc3RyYXRlZ2llcyBhcyB0d28gc2luZ2xlLWZhY3RvciBjb25zdHJ1Y3RzLiBUaGUgaW5kaWNlcyBhcmUgZGVmaW5lZCB1c2luZyBhIGRvdWJseSB3ZWlnaHRlZCBhdmVyYWdlIG9mIHRoZSBwcmluY2lwYWwgY29tcG9uZW50cy4gRm9sbG93aW5nIGNvbW1vbiBwcmFjdGljZSwgd2UgcmVwb3J0IHRoZSB2YWxpZGl0eSBhbmQgcmVsaWFiaWxpdHkgbWVhc3VyZXMgYmVmb3JlIGNhbGN1bGF0aW5nIHRoZSBjb21wb3NpdGUgc2NvcmVzIGZvciB0aGUgdHdvIGNsYXNzaWZpZWQgdGVhY2hpbmcgc3RyYXRlZ2llcy4NCg0KKipWYWxpZGl0eSBNZWFzdXJlcyoqDQoNCmBgYHtyIGVjaG8gPSBUUlVFLCBldmFsID0gVFJVRSwgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KdmFyLm5hbWUgPC1jKCJDb29wb3JhdGl2ZS5jZmEiLCAiRGVkdWN0aXZlLmNmYSIsICJEZW1vbnN0cmF0aW9uLmNmYSIsDQogICAgICAgICAgICAgICJJbmR1Y3RpdmUuY2ZhIiwgIkludGVncmF0aXZlLmNmYSIsICJMZWN0dXJlVHlwZS5jZmEiLA0KICAgICAgICAgICAgICAiUmVwZXRpdGl2ZS5jZmEiKQ0KU3RyYXRlZ2Uud3QucGNhIDwtIGZpbmFsLmFueGlldHkuZGF0WywgdmFyLm5hbWVdDQpuYW1lcyhTdHJhdGVnZS53dC5wY2EpIDwtIGMoIkNvb3BlcmF0aXZlIiwgIkRlZHVjdGl2ZSIsICJEZW1vbnN0cmF0aXZlIiwNCiAgICAgICAgICAgICAgIkluZHVjdGl2ZSIsICJJbnRlZ3JhdGl2ZSIsICJMZWN0dXJlIiwgICAiUmVwZXRpdGl2ZSIpDQoNCg0KDQp0ZWFjaGVyMCA8LSBTdHJhdGVnZS53dC5wY2FbLGMoIkRlZHVjdGl2ZSIsICJEZW1vbnN0cmF0aXZlIiwgIkxlY3R1cmUiLCAiUmVwZXRpdGl2ZSIpXQ0Kc3R1ZGVudDAgPC0gU3RyYXRlZ2Uud3QucGNhWyxjKCJDb29wZXJhdGl2ZSIsICJJbmR1Y3RpdmUiLCAiSW50ZWdyYXRpdmUiLCAiRGVkdWN0aXZlIildDQojIyMNCiMjIw0KdGVhY2hlci52bGlkIDwtY2ZhLmFuYWx5c2lzKHRlYWNoZXIwKQ0Kc3R1ZGVudC52bGlkIDwtY2ZhLmFuYWx5c2lzKHN0dWRlbnQwKQ0KIyMNCnZsaWQudGFibGUgPC1yYmluZCh0ZWFjaGVyLmN0cmQgPSB0ZWFjaGVyLnZsaWQsIHN0dWRlbnQuY3RyZCA9IHN0dWRlbnQudmxpZCkNCnJvdy5uYW1lIDwtIGMoInRlYWNoZXIuY3RyZCIsICJzdHVkZW50LmN0cmQiKQ0Kcm93bmFtZXModmxpZC50YWJsZSkgPC0gcm93Lm5hbWUNCmNvbG5hbWVzKHZsaWQudGFibGUpIDwtIGMoInN0ZC5hbGwubWluIiwJInB2YWwubWF4IiwJInNybXIiLAkiY2ZpIiwJInRsaSIpDQpwYW5kZXIodmxpZC50YWJsZSkNCmBgYA0KDQoqKlJlbGlhYmlsaXR5IE1lYXN1cmVzKioNCg0KYGBge3IgZWNobyA9IFRSVUUsIGV2YWwgPSBUUlVFLCBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmc9RkFMU0V9DQp0ZWFjaGVyIDwtIFN0cmF0ZWdlLnd0LnBjYVssYygiRGVkdWN0aXZlIiwgIkRlbW9uc3RyYXRpdmUiLCAiTGVjdHVyZSIsICJSZXBldGl0aXZlIildDQpzdHVkZW50IDwtIFN0cmF0ZWdlLnd0LnBjYVssYygiQ29vcGVyYXRpdmUiLCAiSW5kdWN0aXZlIiwgIkludGVncmF0aXZlIildDQojIw0KdGVhY2hlci5yZWxpYWJpbGl0eSA8LSBSZWxpYWJpbGl0eS5mdW4odGVhY2hlcikNCnN0dWRlbnQucmVsaWFiaWxpdHkgPC0gUmVsaWFiaWxpdHkuZnVuKHN0dWRlbnQpDQojIw0KUmVsLnRhYmxlIDwtcmJpbmQodGVhY2ggPSBhbnhpZXR5Lm1lYS5yZWwsIGFueGlldHkubWxhID0gYW54aWV0eS5tbGEucmVsKQ0Kcm93Lm5hbWUgPC0gYygiVGVhY2hlciIsICJTdHVkZW50IikNCmNvbC5uYW1lIDwtIGMoIkNyb25iYWNoIGFscGhhIiwgIk1jRG9uYWxkJ3MgT21lZ2EiKQ0Kcm93bmFtZXMoUmVsLnRhYmxlKSA8LSByb3cubmFtZQ0KY29sbmFtZXMoUmVsLnRhYmxlKSA8LSBjb2wubmFtZQ0KcGFuZGVyKFJlbC50YWJsZSkNCmBgYA0KDQpUaGUgYWJvdmUgZ29vZG5lc3Mtb2YtZml0IGFuZCByZWxpYWJpbGl0eSBtZWFzdXJlcyBleGNlZWQgdGhlIHJlcXVpcmVkIHRocmVzaG9sZHMgb2YgdmFsaWRpdHkgYW5kIHJlbGlhYmlsaXR5IG9mIGFuIGluc3RydW1lbnQuIFRoZSAqKmRvdWJseSB3ZWlnaHRlZCBhdmVyYWdlKiogb2YgdGhlIG9yaWdpbmFsIGNvbXBvc2l0ZSBzY29yZXMgb2YgdGVhY2hpbmcgc3RyYXRlZ2llcyBhbmQgYXBwZW5kZWQgdG8gdGhlIGFuYWx5dGljIGRhdGFzZXQuDQoNCg0KYGBge3J9DQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyANCiMjIyMjIA0Kc2NvcmVzID0gZnVuY3Rpb24oZGYsIGRuKXsNCiAgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQogICMjIHNpbmdsZSBmYWN0b3Igc2NvcmUNCiAgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiAgeC52YXIgPC0gbmFtZXMoZGYpDQogIG4wIDwtIGxlbmd0aCh4LnZhcikNCiAgY2ZhLm1vZGVsIDwtICBwYXN0ZSgibGF0ZW50ID1+IiwgcGFzdGUoeC52YXIsIGNvbGxhcHNlID0gIiArICIpKQ0KICBjZmEuZml0IDwtIGNmYShjZmEubW9kZWwsIGRhdGEgPSBkZiwgZXN0aW1hdG9yID0gIk1MTSIpDQogIGNvbXBvc2l0ZS5jZmEgPC0gbGF2UHJlZGljdChjZmEuZml0KQ0KICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KICAjIHBjYSBhbmFseXNpcw0KICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KICBwY2EubWRsIDwtIHByY29tcChkZiwgc2NhbGUgPSBUUlVFKQ0KICBwY2EwIDwtIHBjYS5tZGwkeFssIDFdDQogIHIwID0gY29yKHBjYTAsIGNvbXBvc2l0ZS5jZmEpDQogIGlmKHIwIDwgMCkgew0KICAgICBwY2EuYWxsIDwtIC1wY2EubWRsJHgNCiAgfWVsc2V7DQogICAgcGNhLmFsbCA8LSBwY2EubWRsJHgNCiAgfQ0KICBmaXJzdC5wY2EgPSBwY2EuYWxsWywxXQ0KICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KICAjIHdlaWdodGVkIHBjYSBzY29yZQ0KICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KICB2YXIuZXhwbGFpbmVkIDwtKChwY2EubWRsJHNkZXYpXjIpIC8gc3VtKChwY2EubWRsJHNkZXYpXjIpICMNCiAgY29tcG9zaXRlX3dlaWdodGVkX3BjYSA8LSBhcy5tYXRyaXgocGNhLmFsbCkgJSolICh2YXIuZXhwbGFpbmVkKQ0KDQogIG91dGRhdGEgPC0gYXMuZGF0YS5mcmFtZShjYmluZChwY2ExID0gZmlyc3QucGNhLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHd0LnBjYSA9IGFzLnZlY3Rvcihjb21wb3NpdGVfd2VpZ2h0ZWRfcGNhKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICBjZmEgPSBhcy52ZWN0b3IoY29tcG9zaXRlLmNmYSkpKQ0KICBuYW1lcyhvdXRkYXRhKSA8LSBwYXN0ZTAoZG4sIi4iLCBuYW1lcyhvdXRkYXRhKSwgc2VwID0gIiIpDQogIG91dGRhdGENCiB9DQojIyMNCnRlYWNoZXIgPC0gc2NvcmVzKHRlYWNoZXIsICJUZWFjaGVyLmN0cmQiKQ0Kc3R1ZGVudCA8LSBzY29yZXMoc3R1ZGVudCwgIlN0dWRlbnQuY3RyZCIpDQpBbnhpZXR5LkFuYWx5dGljLkRhdGEgPC0gY2JpbmQoZmluYWxEYXQsIHRlYWNoZXIsIHN0dWRlbnQpDQpgYGANCg0KYGBge3IgZWNobyA9IEZBTFNFLCBldmFsID0gRkFMU0V9DQp3cml0ZS5jc3YoQW54aWV0eS5BbmFseXRpYy5EYXRhLCAiQzpcXFVzZXJzXFw3NUNQRU5HXFxPbmVEcml2ZSAtIFdlc3QgQ2hlc3RlciBVbml2ZXJzaXR5IG9mIFBBXFxEZXNrdG9wXFxjcGVuZ1xcV0NVLVRlYWNoaW5nXFwyMDI1RmFsbFxcTWF0aEF4aWV0eVxcQW54aWV0eS5BbmFseXRpYy5EYXRhLmNzdiIpDQpgYGANCg0KDQoNCiMgTGluZWFyIFJlZ3Jlc3Npb24gQW5hbHlzaXMNCg0KVGhpcyBzZWN0aW9uIG1vdmVzIGZyb20gdGhlIHByZXZpb3VzIGRlc2NyaXB0aXZlIGFuYWx5c2VzIHRvIGEgcmVncmVzc2lvbiBhbmFseXNpcyBvZiB0aGUgYXNzb2NpYXRpb24gYmV0d2VlbiBtYXRoIGFueGlldHkgYW5kIHJlbGF0ZWQgZmFjdG9ycy4gV2UgZXhhbWluZSB0d28gZGlzdGluY3QgYnV0IGludGVyY29ubmVjdGVkIHR5cGVzIG9mIG1hdGggYW54aWV0eSwgZXZhbHVhdGlvbiBhbnhpZXR5IGFuZCBsZWFybmluZyBhbnhpZXR5LCB3aGlsZSB0ZW1wb3JhcmlseSBzZXR0aW5nIGFzaWRlIHRoZWlyIGludGVyY29ubmVjdGlvbi4NCg0KVGhlIHJlZ3Jlc3Npb24gbW9kZWwgYWxzbyBpbmNvcnBvcmF0ZXMgdGhlIHR3byB0ZWFjaGluZyBzdHJhdGVnaWVzIGFzIHByZWRpY3RvciB2YXJpYWJsZXMuIFdlIGFsc28gcmVhbGl6ZWQgdGhhdCB0aGUgdHdvIHZhcmlhYmxlcyBhcmUgY29ycmVsYXRlZC4gDQoNCg0KYGBge3IgZWNobyA9IEZBTFNFLCBldmFsID0gVFJVRX0NCmFueGlldHkuaW5mLmRhdGEwIDwtIHJlYWQuY3N2KCJodHRwczovL3Blbmdkc2NpLmdpdGh1Yi5pby9NYXRoQW54aWV0eS9BbnhpZXR5LkFuYWx5dGljLkRhdGEuY3N2IikNCmluZi52YXIgPC0gYygiQW54aWV0eS5tZWEud3QucGNhIiwgIkFueGlldHkubWxhLnd0LnBjYSIsICJzZXgiLCAicmFjZSIsICJjbGFzcyIsICJtYWpvciIsICJtYXRoLmxldmVsIiwgIm1vZGFsaXR5IiwgIlNlbGZFZmZpY2FjeS53dC5wY2EiLCAiVGVjaG5vbG9neS53dC5wY2EiLA0KICJDb29wb3JhdGl2ZS53dC5wY2EiLCAiRGVkdWN0aXZlLnd0LnBjYSIsICJEZW1vbnN0cmF0aW9uLnd0LnBjYSIsICJJbmR1Y3RpdmUud3QucGNhIiwgICAgIkludGVncmF0aXZlLnd0LnBjYSIsICJMZWN0dXJlVHlwZS53dC5wY2EiLCAiUmVwZXRpdGl2ZS53dC5wY2EiLCAiRW5nYWdlLnd0LnBjYSIsICJSZXNvdXJjZS53dC5wY2EiLCJUZWFjaGVyLmN0cmQud3QucGNhIiwgIlN0dWRlbnQuY3RyZC53dC5wY2EiKQ0KIyMNCmFueGlldHkucmVnLmRhdGEgPC0gYW54aWV0eS5pbmYuZGF0YTBbLCBpbmYudmFyXQ0KcmVnLnZhci5uYW1lIDwtIGMoIk1FQSIsICJNTEEiLCAic2V4IiwgInJhY2UiLCAiY2xhc3MiLCAibWFqb3IiLCAibWF0aC5sZXZlbCIsICJtb2RhbGl0eSIsICJTZWxmRWZmaWNhY3kiLCAiVGVjaG5vbG9neSIsDQogIkNvb3BvcmF0aXZlIiwgIkRlZHVjdGl2ZSIsICJEZW1vbnN0cmF0aW9uIiwgIkluZHVjdGl2ZSIsICAgICJJbnRlZ3JhdGl2ZSIsICJMZWN0dXJlIiwgIlJlcGV0aXRpdmUiLCAiRW5nYWdlIiwgIlJlc291cmNlIiwiVGVhY2hlckN0cmQiLCAiU3R1ZGVudEN0cmQiKQ0KbmFtZXMoYW54aWV0eS5yZWcuZGF0YSkgPC0gcmVnLnZhci5uYW1lIA0KYGBgDQoNCg0KIyMgIEZhY3RvcnMgQXNzb2NpYXRlZCB3aXRoIEV2YWx1YXRpb24gQW54aWV0eQ0KDQpGb3IgdGhlIGFzc29jaWF0aW9uIGFuYWx5c2lzLCB3ZSB3aWxsIGJ1aWxkIHR3byByZWdyZXNzaW9uIG1vZGVscy4gQm90aCBtb2RlbHMgaW5jbHVkZSBhIGNvbW1vbiBzZXQgb2YgZGVtb2dyYXBoaWMgcHJlZGljdG9ycy4gVGhlIGZpcnN0IG1vZGVsIHVzZXMgaW5kaXZpZHVhbCB0ZWFjaGluZyBzdHJhdGVnaWVzIGFzIGFkZGl0aW9uYWwgcHJlZGljdG9ycywgd2hpbGUgdGhlIHNlY29uZCB1c2VzIGdyb3VwZWQgdGVhY2hpbmcgc3RyYXRlZ2llcy4NCg0KIyMjIFVzaW5nIEluZGl2aWR1YWwgVGVhY2hpbmcgU3RyYXRlZ2llcw0KDQpUaGUgYW5hbHlzaXMgYmVnaW5zIHdpdGggYSByZWdyZXNzaW9uIG1vZGVsIGluY29ycG9yYXRpbmcgYWxsIGluZGl2aWR1YWwgdGVhY2hpbmcgYXBwcm9hY2hlcyBhbG9uZ3NpZGUgZGVtb2dyYXBoaWMgYW5kIHJlbGF0ZWQgdmFyaWFibGVzIGFzIHByZWRpY3RvcnMuDQoNCmBgYHtyfQ0KQmVzdFN1YnNldHNSZWcgPC0gZnVuY3Rpb24oYmVzdC5zdWJzZXQubW9kZWwpew0KICAgIyBWaWV3IHRoZSByZXN1bHRzDQogICByZWcuc3VtbWFyeSA8LSBzdW1tYXJ5KGJlc3Quc3Vic2V0Lm1vZGVsKQ0KIA0KICAgIyBQbG90dGluZyB0aGUgcmVzdWx0cyAob3B0aW9uYWwsIGZvciB2aXN1YWxpemF0aW9uKQ0KICAgIyBwbG90KGJlc3Quc3Vic2V0Lm1vZGVsLCBzY2FsZSA9ICJhZGpyMiIsIGNvbCA9ICJza3libHVlIikgIyBvciAiYmljIiwgImNwIiwgZXRjLg0KICAgcGFyKG1mcm93ID0gYygyLDIpKQ0KICAgcGxvdChyZWcuc3VtbWFyeSRyc3MsIHhsYWIgPSAiTnVtYmVyIG9mIFZhcmlhYmxlcyIsIHlsYWIgPSAiUlNTIiwgdHlwZSA9ICJsIiwgY29sID0gIm5hdnkiKQ0KICAgcGxvdChyZWcuc3VtbWFyeSRhZGpyMiwgeGxhYiA9ICJOdW1iZXIgb2YgVmFyaWFibGVzIiwgeWxhYiA9ICJBZGp1c3RlZCBSU3EiLCB0eXBlID0gImwiLCBjb2wgPSAibmF2eSIpDQogICAjIFdlIHdpbGwgbm93IHBsb3QgYSByZWQgZG90IHRvIGluZGljYXRlIHRoZSBtb2RlbCB3aXRoIHRoZSBsYXJnZXN0IGFkanVzdGVkIFJeMiBzdGF0aXN0aWMuDQogICAjIFRoZSB3aGljaC5tYXgoKSBmdW5jdGlvbiBjYW4gYmUgdXNlZCB0byBpZGVudGlmeSB0aGUgbG9jYXRpb24gb2YgdGhlIG1heGltdW0gcG9pbnQgb2YgYSB2ZWN0b3INCiAgIGFkai5yMi5tYXggPSB3aGljaC5tYXgocmVnLnN1bW1hcnkkYWRqcjIpIA0KDQogICAjIFRoZSBwb2ludHMoKSBjb21tYW5kIHdvcmtzIGxpa2UgdGhlIHBsb3QoKSBjb21tYW5kLCBleGNlcHQgdGhhdCBpdCBwdXRzIHBvaW50cyANCiAgICMgb24gYSBwbG90IHRoYXQgaGFzIGFscmVhZHkgYmVlbiBjcmVhdGVkIGluc3RlYWQgb2YgY3JlYXRpbmcgYSBuZXcgcGxvdA0KICAgcG9pbnRzKGFkai5yMi5tYXgsIHJlZy5zdW1tYXJ5JGFkanIyW2Fkai5yMi5tYXhdLCBjb2wgPSJkYXJrcmVkIiwgY2V4ID0gMiwgcGNoID0gMjApDQogICAjIFdlJ2xsIGRvIHRoZSBzYW1lIGZvciBDX3AgYW5kIEJJQywgdGhpcyB0aW1lIGxvb2tpbmcgZm9yIHRoZSBtb2RlbHMgd2l0aCB0aGUgU01BTExFU1Qgc3RhdGlzdGljDQogICBwbG90KHJlZy5zdW1tYXJ5JGNwLCB4bGFiID0gIk51bWJlciBvZiBWYXJpYWJsZXMiLCB5bGFiID0gIkNwIiwgdHlwZSA9ICJsIikNCiAgIGNwLm1pbiA9IHdoaWNoLm1pbihyZWcuc3VtbWFyeSRjcCkgIyAxMA0KICAgcG9pbnRzKGNwLm1pbiwgcmVnLnN1bW1hcnkkY3BbY3AubWluXSwgY29sID0gImRhcmtyZWQiLCBjZXggPSAyLCBwY2ggPSAyMCkNCg0KICAgcGxvdChyZWcuc3VtbWFyeSRiaWMsIHhsYWIgPSAiTnVtYmVyIG9mIFZhcmlhYmxlcyIsIHlsYWIgPSAiQklDIiwgdHlwZSA9ICJsIikNCiAgIGJpYy5taW4gPSB3aGljaC5taW4ocmVnLnN1bW1hcnkkYmljKSAjIDYNCiAgIHBvaW50cyhiaWMubWluLCByZWcuc3VtbWFyeSRiaWNbYmljLm1pbl0sIGNvbCA9ICJkYXJrcmVkIiwgY2V4ID0gMiwgcGNoID0gMjApDQp9DQpgYGANCg0KYGBge3IgZWNobyA9IFRSVUUsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9NX0NCm1lYS5sbS5kYXRhIDwtIGFueGlldHkucmVnLmRhdGFbLC1jKDIsMjAsMjEpXQ0KbWVhLmJlc3Quc3Vic2V0cy5sbSA8LSByZWdzdWJzZXRzKE1FQSB+LiwgZGF0YSA9IG1lYS5sbS5kYXRhLCBudm1heCA9IDgsICBtZXRob2QgPSAiYmFja3dhcmQiICkNCkJlc3RTdWJzZXRzUmVnKG1lYS5iZXN0LnN1YnNldHMubG0pDQpgYGANCg0KVGhlIGFib3ZlIGZpZ3VyZSBpbmRpY2F0ZXMgdGhhdCB0aGUgNi1wcmVkaWN0b3IgbW9kZWwgaXMgdGhlIG9wdGltYWwgY2hvaWNlLiBUaGUgcmVzdWx0cyBvYnRhaW5lZCBmcm9tIHRoaXMgc3Vic2V0IHNlbGVjdGlvbiBtZXRob2QgYXJlIGlkZW50aWNhbCB0byB0aG9zZSBvYnRhaW5lZCB2aWEgc3RlcHdpc2UgdmFyaWFibGUgc2VsZWN0aW9uLg0KDQpgYGB7ciBlY2hvID0gVFJVRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NywgZmlnLmhlaWdodD03fQ0KbWVhLmxtLmRhdGEgPC0gYW54aWV0eS5yZWcuZGF0YVssLWMoMiwyMCwyMSldDQptZWEubG0gPC0gbG0oTUVBIH5TZWxmRWZmaWNhY3kgKyBJbmR1Y3RpdmUgKyBJbnRlZ3JhdGl2ZSArIG1hdGgubGV2ZWwgKyBzZXggKw0KICAgIFRlY2hub2xvZ3ksIGRhdGEgPSBtZWEubG0uZGF0YSkNCnN0ZXB3aXNlLm1lYS5tb2RlbCA8LSBzdGVwQUlDKG1lYS5sbSwgZGlyZWN0aW9uID0gImJvdGgiLCB0cmFjZSA9IDApDQojc3VtbWFyeShzdGVwd2lzZS5tZWEubW9kZWwpDQpwYXIobWZyb3cgPSBjKDIsMikpDQpwbG90KHN0ZXB3aXNlLm1lYS5tb2RlbCApDQpgYGANCg0KVGhlIGZpZ3VyZSBhYm92ZSByZXZlYWxzIGEgY2xlYXIgcGF0dGVybiBvZiBub24tY29uc3RhbnQgcmVzaWR1YWwgdmFyaWFuY2UgKGhldGVyb3NjZWRhc3RpY2l0eSkgYXMgdGhlIGZpdHRlZCB2YWx1ZXMgaW5jcmVhc2UuIEJlY2F1c2UgdGhlIHJlc3BvbnNlIHZhcmlhYmxlIGluY2x1ZGVzIG5lZ2F0aXZlIHZhbHVlcywgYSBzdGFuZGFyZCBCb3gtQ294IHRyYW5zZm9ybWF0aW9uIGlzIG5vdCBhcHBsaWNhYmxlIGZvciBpZGVudGlmeWluZyBhIHBvd2VyIHRyYW5zZm9ybWF0aW9uLiBJbnN0ZWFkLCB3ZSB3aWxsIHVzZSBib290c3RyYXAgY29uZmlkZW5jZSBpbnRlcnZhbHMgZm9yIGFsbCByZWdyZXNzaW9uIGNvZWZmaWNpZW50cyB0byBhc3Nlc3MgdGhlaXIgc2lnbmlmaWNhbmNlLCB0aGVyZWJ5IG1haW50YWluaW5nIHRoZSByZXNwb25zZSB2YXJpYWJsZSBvbiBpdHMgb3JpZ2luYWwgc2NhbGUuDQoNCg0KYGBge3J9DQojIyMgQm9vdHN0cmFwIGNvbmZpZGVuY2UgaW50ZXJ2YWxzDQpib290LmNvZWYgPC0gZnVuY3Rpb24oZGF0YSwgaW5kaWNlcykgew0KICBkIDwtIGRhdGFbaW5kaWNlcywgXSAgIyByZXNhbXBsZSByb3dzDQogIGZpdCA8LSBsbShNRUEgfiBTZWxmRWZmaWNhY3kgKyBJbnRlZ3JhdGl2ZSArIG1hdGgubGV2ZWwgKyANCiAgICBzZXggKyBUZWNobm9sb2d5LCBkYXRhID0gZCkNCiAgcmV0dXJuKGNvZWYoZml0KSkgICAgICAjIHJldHVybiBjb2VmZmljaWVudHMNCn0NCiMjIyMjIw0KIyBFeHRyYWN0IENJcyBmb3IgYWxsIGNvZWZmaWNpZW50cw0KZ2V0LmFsbC5ib290LmNpcyA8LSBmdW5jdGlvbihib290Lm91dHB1dCwgdHlwZSA9ICJwZXJjIikgew0KICBuLmNvZWYgPC0gbmNvbChib290Lm91dHB1dCR0KQ0KICBjaS5tYXRyaXggPC0gbWF0cml4KE5BLCBucm93ID0gbi5jb2VmLCBuY29sID0gMikNCiAgcm93bmFtZXMoY2kubWF0cml4KSA8LSBjb2xuYW1lcyhib290Lm91dHB1dCR0KQ0KICBjb2xuYW1lcyhjaS5tYXRyaXgpIDwtIGMoImJ0Lmxvdy45NSUiLCAiYnQudXAuOTUlIikNCiAgDQogIGZvciAoaSBpbiAxOm4uY29lZikgew0KICAgIGNpLm9iaiA8LSBib290LmNpKGJvb3Qub3V0cHV0LCB0eXBlID0gdHlwZSwgaW5kZXggPSBpKQ0KICAgIGlmICh0eXBlID09ICJwZXJjIikgew0KICAgICAgY2kubWF0cml4W2ksIF0gPC0gY2kub2JqJHBlcmNlbnRbNDo1XQ0KICAgIH0NCiAgfQ0KICANCiAgcmV0dXJuKGNpLm1hdHJpeCkNCn0NCg0KYGBgDQoNCmBgYHtyfQ0KIyBQZXJmb3JtIGJvb3RzdHJhcCAoUiA9IG51bWJlciBvZiByZXNhbXBsZXMpDQpzZXQuc2VlZCgzMTEpICAjIGZvciByZXByb2R1Y2liaWxpdHkNCmJvb3QucmVzdWx0cyA8LSBib290KG1lYS5sbS5kYXRhLCBib290LmNvZWYsIFIgPSAxMDAwKQ0KYGBgDQoNCmBgYHtyfQ0KYWxsLmNpcyA8LSBnZXQuYWxsLmJvb3QuY2lzKGJvb3QucmVzdWx0cykNCkluZmVyZW5jZVRhYmxlIDwtIHJvdW5kKGNiaW5kKHN1bW1hcnkoc3RlcHdpc2UubWVhLm1vZGVsKSRjb2VmLCBhbGwuY2lzKSw0KQ0KcHJpbnQoSW5mZXJlbmNlVGFibGUpIA0KYGBgDQoNCg0KDQpUaGUgYWJvdmUgdGFibGUgcmV2ZWFsZWQgc2V2ZXJhbCBzaWduaWZpY2FudCBwcmVkaWN0b3JzIG9mIG1hdGggZXZhbHVhdGlvbiBhbnhpZXR5LiBIaWdoZXIgKipzZWxmLWVmZmljYWN5Kiogd2FzIHN0cm9uZ2x5IGFzc29jaWF0ZWQgd2l0aCBsb3dlciBhbnhpZXR5ICgkXGJldGEgPSAtMC41NzcsIHAgPCAwLjAwMSQpLCBpbmRpY2F0aW5nIHRoYXQgc3R1ZGVudHMgd2hvIGFyZSBtb3JlIGNvbmZpZGVudCBpbiB0aGVpciBtYXRoZW1hdGljYWwgYWJpbGl0aWVzIGV4cGVyaWVuY2UgbGVzcyAqKmV2YWx1YXRpb24tcmVsYXRlZCBzdHJlc3MqKi4gU2ltaWxhcmx5LCAqKmludGVncmF0aXZlIGluc3RydWN0aW9uIGFwcHJvYWNoKiogc2hvd2VkIGEgbmVnYXRpdmUgcmVsYXRpb25zaGlwIHdpdGggYW54aWV0eSAoJFxiZXRhID0gLTAuMTc4LCBwIDwgMC4wMDEkKSwgIGltcGx5aW5nIHRoYXQgdGhpcyB0ZWFjaGluZyBtZXRob2QgbWF5IGhlbHAgcmVkdWNlIHN0dWRlbnQgYW54aWV0eS4gKipDb3Vyc2UgbGV2ZWwqKiBhbHNvIHBsYXllZCBhIHJvbGU6IHN0dWRlbnRzIGVucm9sbGVkIGluIG1hdGgwMyAoY2FsYyBBIGFuZCBicmllZiBDYWxjKSAoJFxiZXRhID0gMC4yNzYsIHAgPSAwLjA0MCQpIGFuZCBtYXRoMDQgKGFib3ZlIENhbGMgQSkgKCRcYmV0YSA9IDAuMzYzLCBwID0gMC4wMjMkKSBjb3Vyc2VzIGV4aGliaXRlZCBoaWdoZXIgYW54aWV0eSBjb21wYXJlZCB0byB0aGUgcmVmZXJlbmNlIGdyb3VwLCB3aGlsZSBvdGhlciBjb3Vyc2UgbGV2ZWxzIHdlcmUgbm90IHNpZ25pZmljYW50LiAqKkdlbmRlcioqIHdhcyBhIHNpZ25pZmljYW50IGZhY3Rvciwgd2l0aCBtYWxlIHN0dWRlbnRzIHJlcG9ydGluZyBsb3dlciBhbnhpZXR5IHRoYW4gZmVtYWxlcyAoJFxiZXRhID0gLTAuMzQ0LCBwIDwgMC4wMDEkKS4gRmluYWxseSwgKip0ZWNobm9sb2d5IHVzZSoqIHdhcyBuZWdhdGl2ZWx5IGFzc29jaWF0ZWQgd2l0aCBhbnhpZXR5ICgkXGJldGEgPSAtMC4xMzcsIHAgPCAwLjAwMSQpLCBpbmRpY2F0aW5nIHRoYXQgZ3JlYXRlciBlbmdhZ2VtZW50IHdpdGggdGVjaG5vbG9neSBjb3JyZXNwb25kcyB0byByZWR1Y2VkIG1hdGggZXZhbHVhdGlvbiBhbnhpZXR5LiANCg0KSW4gc3VtbWFyeSwgbWF0aCBldmFsdWF0aW9uIGFueGlldHkgd2FzIHNpZ25pZmljYW50bHkgbG93ZXIgYW1vbmcgc3R1ZGVudHMgd2l0aCBoaWdoZXIgKipzZWxmLWVmZmljYWN5KiouICBBbiAqKmludGVncmF0aXZlIHRlYWNoaW5nIGFwcHJvYWNoKiogYW5kIGFwcHJvcHJpYXRlICoqdXNlIG9mIHRlY2hub2xvZ3kqKiBtYXkgaGVscCByZWR1Y2UgbWF0aCBldmFsdWF0aW9uIGFueGlldHkuIE1hbGUgc3R1ZGVudHMgdGVuZGVkIHRvIGV4cGVyaWVuY2UgbGVzcyBzdHJlc3MuIENvbnZlcnNlbHksIHN0dWRlbnRzIGVucm9sbGVkIGluIGhpZ2hlci1sZXZlbCBtYXRoIGNvdXJzZXMgKG1hdGgwMyBhbmQgbWF0aDA0KSByZXBvcnRlZCBzbGlnaHRseSBoaWdoZXIgYW54aWV0eS4gDQoNCg0KIyMjIFVzaW5nIEdyb3VwZWQgVGVhY2hpbmcgU3RyYXRlZ2llcw0KDQpOZXh0LCB3ZSBidWlsZCBhIHJlZ3Jlc3Npb24gbW9kZWwgdXNpbmcgdGhlIGFnZ3JlZ2F0ZWQgdGVhY2hpbmcgc3R5bGVzOiB0ZWFjaGVyLWNlbnRlcmVkIGFuZCBzdHVkZW50LWNlbnRlcmVkLCBwbHVzIHNvbWUgZGVtb2dyYXBoaWMgZmFjdG9ycy4NCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NywgZmlnLmhlaWdodD02fQ0KIyBQZXJmb3JtIGJlc3Qgc3Vic2V0IHNlbGVjdGlvbg0KIyAnbnZtYXgnIHNwZWNpZmllcyB0aGUgbWF4aW11bSBudW1iZXIgb2YgdmFyaWFibGVzIHRvIGNvbnNpZGVyIGluIGEgc3Vic2V0DQpiZXN0LnN1YnNldC5tb2RlbC5jdHJkIDwtIHJlZ3N1YnNldHMoTUVBfiBzZXgrIHJhY2UrIGNsYXNzKyBtYWpvcisgbWF0aC5sZXZlbCsgbW9kYWxpdHkrIFNlbGZFZmZpY2FjeSsgVGVjaG5vbG9neSArIFRlYWNoZXJDdHJkKyBTdHVkZW50Q3RyZCwgZGF0YSA9IGFueGlldHkucmVnLmRhdGEsIG52bWF4ID0gMTAsICBtZXRob2QgPSAiYmFja3dhcmQiICkNCkJlc3RTdWJzZXRzUmVnKGJlc3Quc3Vic2V0Lm1vZGVsLmN0cmQpDQpgYGANCg0KYGBge3J9DQpjb2VmKGJlc3Quc3Vic2V0Lm1vZGVsLmN0cmQsNikNCmBgYA0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NywgZmlnLmhlaWdodD02fQ0KIyBUaGUgZmluYWwgbW9kZWwNCmJlc3Quc3Vic2V0LmN0cmQgPC0gbG0oTUVBfiBzZXgrIG1hdGgubGV2ZWwrICBTZWxmRWZmaWNhY3krIFRlY2hub2xvZ3kgKyBTdHVkZW50Q3RyZCwgZGF0YSA9IGFueGlldHkucmVnLmRhdGEpDQojc3VtbWFyeShiZXN0LnN1YnNldC5jdHJkKSRjb2VmDQpwYXIobWZyb3cgPSBjKDIsMikpDQpwbG90KGJlc3Quc3Vic2V0LmN0cmQpDQpgYGANCg0KV2UgbmV4dCBwZXJmb3JtIEJvb3RzdHJhcCByZWdyZXNzaW9uIHRvIGNvbnN0cnVjdCByb2J1c3QgY29uZmlkZW5jZSBpbnRlcnZhbHMgZm9yIHRoZSByZWdyZXNzaW9uIGNvZWZmaWNpZW50cy4NCg0KYGBge3J9DQojIyMgQm9vdHN0cmFwIGNvbmZpZGVuY2UgaW50ZXJ2YWxzDQpib290LmNvZWYuY3RyZCA8LSBmdW5jdGlvbihkYXRhLCBpbmRpY2VzKSB7DQogIGQgPC0gZGF0YVtpbmRpY2VzLCBdICAjIHJlc2FtcGxlIHJvd3MNCiAgZml0IDwtIGxtKE1FQX4gc2V4KyBtYXRoLmxldmVsKyAgU2VsZkVmZmljYWN5KyBUZWNobm9sb2d5ICsgU3R1ZGVudEN0cmQsIGRhdGEgPSBkKQ0KICByZXR1cm4oY29lZihmaXQpKSAgICAgICMgcmV0dXJuIGNvZWZmaWNpZW50cw0KfQ0KYGBgDQoNCg0KYGBge3J9DQojIFBlcmZvcm0gYm9vdHN0cmFwIChSID0gbnVtYmVyIG9mIHJlc2FtcGxlcykNCnNldC5zZWVkKDMxMikgICMgZm9yIHJlcHJvZHVjaWJpbGl0eQ0KYm9vdC5yZXN1bHRzLmN0cmQgPC0gYm9vdChhbnhpZXR5LnJlZy5kYXRhLCBib290LmNvZWYuY3RyZCwgUiA9IDEwMDApDQpgYGANCg0KYGBge3J9DQphbGwuY3RyZC5jaXMgPC0gZ2V0LmFsbC5ib290LmNpcyhib290LnJlc3VsdHMuY3RyZCApDQpJbmZlcmVuY2VUYWJsZSA8LSByb3VuZChjYmluZChzdW1tYXJ5KGJlc3Quc3Vic2V0LmN0cmQpJGNvZWYsIGFsbC5jdHJkLmNpcyApLDQpDQpwcmludChJbmZlcmVuY2VUYWJsZSkgDQpgYGANCg0KVGhlIHJlc3VsdHMgYWJvdmUgYXJlIGNvbnNpc3RlbnQgd2l0aCB0aGUgcHJldmlvdXMgcmVncmVzc2lvbiB0aGF0IHVzZWQgaW5kaXZpZHVhbCB0ZWFjaGluZyBzdHJhdGVnaWVzIGFzIHByZWRpY3RvcnMuIFRoZSBrZXkgZGlmZmVyZW5jZSBpcyB0aGF0IHRoZSAqKmludGVncmF0aXZlIHRlYWNoaW5nIGFwcHJvYWNoKiogd2FzIHNpZ25pZmljYW50IGluIHRoZSBmb3JtZXIgbW9kZWwsIHdoZXJlYXMgKipzdHVkZW50LWNlbnRlcmVkKiogdGVhY2hpbmcgc3RyYXRlZ2llcyBhcmUgc2lnbmlmaWNhbnQgaW4gdGhlIGN1cnJlbnQgb25lLiBIb3dldmVyLCBzaW5jZSBhbiBpbnRlZ3JhdGl2ZSBhcHByb2FjaCBpcyBhIHNwZWNpZmljIHR5cGUgb2Ygc3R1ZGVudC1jZW50ZXJlZCBzdHJhdGVneSwgdGhlIG1vZGVscyB1bHRpbWF0ZWx5IHlpZWxkIGNvbmdydWVudCBmaW5kaW5ncy4NCg0KDQoNCiMjIEZhY3RvcnMgQXNzb2NpYXRlZCB3aXRoIExlYXJuaW5nIEFueGlldHkNCg0KVW5saWtlIG1hdGggZXZhbHVhdGlvbiBhbnhpZXR5LCB3aGljaCBpcyBmdWVsZWQgbW9yZSBieSBlbW90aW9uYWwgYW5kIGVudmlyb25tZW50YWwgZmFjdG9ycywgbWF0aCBsZWFybmluZyBhbnhpZXR5IGlzIGEgZGlyZWN0IHJlc3BvbnNlIHRvIHRoZSBsZWFybmluZyBlY29zeXN0ZW0uIEl0IGlzIGNsb3NlbHkgbGlua2VkIHRvIHRoZSBkZW5zaXR5IG9mIHRoZSBsZWFybmluZyBtYXRlcmlhbHMsIHRoZSBzaWduaWZpY2FudCBjb2duaXRpdmUgbG9hZCByZXF1aXJlZCBmb3IgcHJvYmxlbS1zb2x2aW5nLCBhbmQgY3JpdGljYWwgZXh0ZXJuYWwgZmFjdG9ycyBzdWNoIGFzIGluc3RydWN0b3JzJyB0ZWFjaGluZyBzdHJhdGVnaWVzLiANCg0KVGhlIG5leHQgcmVncmVzc2lvbiBtb2RlbCBhaW1zIHRvIGlkZW50aWZ5IGZhY3RvcnMgdGhhdCBhcmUgZGlyZWN0bHkgYXNzb2NpYXRlZCB3aXRoIHRoZSBtYXRoIGxlYXJuaW5nIGFueGlldHkuIFdlIHN0aWxsIHRha2UgdGhlIGJlc3Qgc3Vic2V0IHNlbGVjdGlvbiBhcHByb2FjaCB0byBpZGVudGlmeWluZyB0aGUgYmVzdCBtb2RlbC4NCg0KDQojIyMgVXNpbmcgSW5kaXZpZHVhbCBUZWFjaGluZyBTdHJhdGVnaWVzDQoNClRoZSBmb2xsb3dpbmcgbW9kZWwgdXNlcyBpbmRpdmlkdWFsIHRlYWNoaW5nIHN0cmF0ZWdpZXMgYXMgcHJlZGljdG9ycy4gVGhpcyB3aWxsIGhlbHAgaWRlbnRpZnkgcGFydGljdWxhciB0ZWFjaGluZyBzdHJhdGVnaWVzIHRoYXQgYXJlIHNpZ25pZmljYW50bHkgYXNzb2NpYXRlZCB3aXRoIHRoZSBsZWFuaW5nIGFueGlldHkuDQoNCg0KYGBge3IgZWNobyA9IFRSVUUsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9Nn0NCm1sYS5sbS5kYXRhIDwtIGFueGlldHkucmVnLmRhdGFbLC1jKDEsMjAsMjEpXQ0KbWxhLmZ1bGwubG0gPC0gbG0oTUxBIH4uLCBkYXRhID0gbWxhLmxtLmRhdGEpDQpwYXIobWZyb3cgPSBjKDIsMikpDQpwbG90KG1sYS5mdWxsLmxtKQ0KI3N1bW1hcnkobWxhLmZ1bGwubG0pDQpgYGANCg0KDQpUaGlzIGluaXRpYWwgbW9kZWwncyByZXNpZHVhbCBkaWFnbm9zdGljIHBsb3Qgc2hvd3Mgbm9uLWNvbnN0YW50IHZhcmlhbmNlLiBXZSB3aWxsIG5vdCBwZXJmb3JtIGFueSBwb3dlciB0cmFuc2Zvcm1hdGlvbnMgb24gdGhlIHJlc3BvbnNlIHZhcmlhYmxlIGZvciB0aGUgc2FtZSByZWFzb25zIHN0YXRlZCBpbiB0aGUgcHJldmlvdXMgc3Vic2VjdGlvbi4gVGhlIGluZmVyZW5jZSBvbiB0aGUgcmVncmVzc2lvbiBjb2VmZmljaWVudHMgd2lsbCBiYXNlZCBvbiBub25wYXJhbWV0cmljIEJvb3RzdHJhcCBhbmQgdGhlIGNsYXNzaWNhbCB0LXRlc3RzLg0KDQpXZSBuZXh0IHVzZSBiZXN0IHN1YnNldCBtb2RlbCBzZWxlY3Rpb24gYXBwcm9hY2ggdG8gaWRlbnRpZnkgdGhlIG9wdGltYWwgbW9kZWwgdXNpbmcgdmFyaW91cyBwZXJmb3JtYW5jZSBtZWFzdXJlcyBzdWNoIGFzIENwLCBCSUMsIEFkanVzdGVkIGNvZWZmaWNpZW50IG9mIGRldGVybWluYXRpb24gYW5kIHRoZSBsaXN0IG9mIHRoZSBzaWduaWZpY2FudCBwcmVkaWN0b3JzIGluIHRoZSBpbml0aWFsIG1vZGVsIHdpdGggbW9zdCBvZiB0aGUgY2FuZGlkYXRlIHByZWRpY3RvciB2YXJpYWJsZXMuIA0KDQoNCmBgYHtyIGVjaG8gPSBUUlVFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD03LCBmaWcuaGVpZ2h0PTV9DQptbGEuYmVzdC5zdWJzZXRzLmxtIDwtIHJlZ3N1YnNldHMoTUxBIH4uLCBkYXRhID0gbWxhLmxtLmRhdGEsIG52bWF4ID0gMTYsICBtZXRob2QgPSAiYmFja3dhcmQiICkNCkJlc3RTdWJzZXRzUmVnKG1sYS5iZXN0LnN1YnNldHMubG0pDQpgYGANCg0KYGBge3J9DQpwcmVkLnZhciA8LSBuYW1lcyhjb2VmKG1sYS5iZXN0LnN1YnNldHMubG0gLDcpKVstKDE6MildDQphY3V0YWwudmFyIDwtYygicmFjZSIsIHByZWQudmFyKQ0KZm9ybXVsYS5zdHIgPC0gcGFzdGUoIk1MQSIsICJ+IiwgcGFzdGUoYWN1dGFsLnZhciwgY29sbGFwc2UgPSAiICsgIikpDQpNTEEubW9kZWwuZm9ybXVsYSA8LSBhcy5mb3JtdWxhKGZvcm11bGEuc3RyKQ0KTUxBLm1vZGVsIDwtIGxtKE1MQS5tb2RlbC5mb3JtdWxhICwgZGF0YSA9IG1sYS5sbS5kYXRhKQ0Kc3VtbWFyeShNTEEubW9kZWwgKQ0KYGBgDQoNCmBgYHtyfQ0KIyMjIEJvb3RzdHJhcCBjb25maWRlbmNlIGludGVydmFscw0KYm9vdC5jb2VmLm1sYSA8LSBmdW5jdGlvbihkYXRhLCBpbmRpY2VzKSB7DQogIGQgPC0gZGF0YVtpbmRpY2VzLCBdICAjIHJlc2FtcGxlIHJvd3MNCiAgZml0IDwtIGxtKE1MQS5tb2RlbC5mb3JtdWxhLCBkYXRhID0gZCkNCiAgcmV0dXJuKGNvZWYoZml0KSkgICAgICAjIHJldHVybiBjb2VmZmljaWVudHMNCn0NCmBgYA0KDQpgYGB7cn0NCiMgUGVyZm9ybSBib290c3RyYXAgKFIgPSBudW1iZXIgb2YgcmVzYW1wbGVzKQ0Kc2V0LnNlZWQoMzEyKSAgIyBmb3IgcmVwcm9kdWNpYmlsaXR5DQpib290LnJlc3VsdHMubWxhPC0gYm9vdChtbGEubG0uZGF0YSwgYm9vdC5jb2VmLm1sYSwgUiA9IDEwMDApDQpgYGANCg0KDQpgYGB7cn0NCmFsbC5jaXMubWxhIDwtIGdldC5hbGwuYm9vdC5jaXMoYm9vdC5yZXN1bHRzLm1sYSkNCkluZmVyZW5jZVRhYmxlIDwtIHJvdW5kKGNiaW5kKHN1bW1hcnkoTUxBLm1vZGVsKSRjb2VmLCBhbGwuY2lzLm1sYSksNCkNCnByaW50KEluZmVyZW5jZVRhYmxlKSANCmBgYA0KDQpUaGUgYWJvdmUgcmVzdWx0cyBpbmRpY2F0ZSB0aGF0ICoqU2VsZi1FZmZpY2FjeSoqLCAqKlRlY2hub2xvZ3kgdXNlKiosICoqRGVtb25zdHJhdGlvbioqLCBhbmQgKipMZWN0dXJlLWJhc2VkKiogdGVhY2hpbmcgc3RyYXRlZ2llcyBhcmUgc2lnbmlmaWNhbnQgbmVnYXRpdmUgcHJlZGljdG9ycyBvZiBhbnhpZXR5LiBTcGVjaWZpY2FsbHksIGhpZ2hlciBzZWxmLWVmZmljYWN5ICgkXGJldGEgPSAtMC40MCwgcCA8IC4wMDEkKSBhbmQgZ3JlYXRlciB1c2Ugb2YgKip0ZWNobm9sb2d5KiogaW4gbGVhcm5pbmcgKCRcYmV0YSA9IC0wLjExLCBwIDwgLjAwMSQpIGFyZSBhc3NvY2lhdGVkIHdpdGggbG93ZXIgbGV2ZWxzIG9mIG1hdGggbGVhcm5pbmcgYW54aWV0eS4gU2ltaWxhcmx5LCBtb3JlIGZyZXF1ZW50IHVzZSBvZiAqKmRlbW9uc3RyYXRpdmUqKiAoJFxiZXRhID0gLTAuMTAsIHAgPSAuMDA2JCkgYW5kICoqbGVjdHVyZSBhcHByb2FjaGVzKiogKCRcYmV0YSA9IC0wLjE0LCBwIDwgLjAwMSQpIGNvcnJlc3BvbmQgd2l0aCBkZWNyZWFzZWQgYW54aWV0eS4NCg0KQ29udmVyc2VseSwgdGhlIHBlcmNlaXZlZCAqKkNvb3BlcmF0aXZlKiogdGVhY2hpbmcgYXBwcm9hY2ggaXMgcG9zaXRpdmVseSBhc3NvY2lhdGVkIHdpdGggbGVhcm5pbmcgYW54aWV0eSAoJFxiZXRhID0gMC4wNywgcCA9IC4wMzEkKS4gICoqUmVzb3VyY2UtYmFzZWQqKiBsZWFybmluZyAoJFxiZXRhID0gMC4wOCwgcCA9IC4wMTMkKSBpcyBhbHNvIHBvc2l0aXZlbHkgYXNzb2NpYXRlZCB3aXRoIGFueGlldHksIHN1Z2dlc3RpbmcgdGhhdCBzdHVkZW50IHVzZWQgbGVhcm5pbmcgcmVzb3VyY2VzIHRlbmRlZCB0byBoYXZlIGhpZ2hlciBhbnhpZXR5IGluIG1hdGggY29udGV4dHMuDQoNClRoZSByYWNlIHZhcmlhYmxlIGFwcHJvYWNoZWQgbWFyZ2luYWwgc2lnbmlmaWNhbmNlIChwID0wLjA1OCksIGluZGljYXRpbmcgdGhhdCBCbGFjayBzdHVkZW50cyB0ZW5kZWQgdG8gaGF2ZSBoaWdoZXIgbGVhcm5pbmcgYW54aWV0eSAoJFxiZXRhID0gMC4zMjAyLCBwID0gLjA1OCQpLg0KDQpPdmVyYWxsLCB0aGVzZSByZXN1bHRzIGhpZ2hsaWdodCB0aGF0IHN0dWRlbnRz4oCZIGNvbmZpZGVuY2UgaW4gdGhlaXIgbWF0aCBhYmlsaXRpZXMgYW5kIGNlcnRhaW4gaW5zdHJ1Y3Rpb25hbCBwcmFjdGljZXMgcGxheSBhIGtleSByb2xlIGluIHJlZHVjaW5nIG1hdGggbGVhcm5pbmcgYW54aWV0eSwgd2hpbGUgb3RoZXJzIG1heSBpbmFkdmVydGVudGx5IGluY3JlYXNlIGl0Lg0KDQoNCiMjIyBVc2luZyBHcm91cGVkIFRlYWNoaW5nIFN0cmF0ZWdpZXMNCg0KV2UgbmV4dCBidWlsZCBhIHJlZ3Jlc3Npb24gc2ltaWxhciB0byB0aGUgYWJvdmUgb25lIGJ1dCByZXBsYWNlIHRoZSBpbmRpdmlkdWFsIHRlYWNoaW5nIHN0cmF0ZWd5IHZhcmlhYmxlcyB3aXRoIHRoZSB0d28gZ3JvdXBlZCB0ZWFjaGluZyBzdHJhdGVneSB2YXJpYWJsZXM6IHRlYWNoZXItY2VudGVyZWQgYW1kIHN0dWRlbnQtY2VudGVyZWQgYXBwcm9hY2hlcy4NCg0KDQpgYGB7ciBlY2hvID0gVFJVRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NywgZmlnLmhlaWdodD02fQ0KbWxhLmxtLmRhdGEuY3RyZCA8LSBhbnhpZXR5LnJlZy5kYXRhWywtYygxLCAxMToxNyldDQptbGEuZnVsbC5jdHJkIDwtIGxtKE1MQSB+LiwgZGF0YSA9IG1sYS5sbS5kYXRhLmN0cmQpDQpwYXIobWZyb3cgPSBjKDIsMikpDQpwbG90KG1sYS5mdWxsLmN0cmQpDQojIHN1bW1hcnkobWxhLmZ1bGwuY3RyZCkNCmBgYA0KDQoNCmBgYHtyIGVjaG8gPSBUUlVFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD03LCBmaWcuaGVpZ2h0PTV9DQptbGEuYmVzdC5zdWJzZXRzLmN0cmQgPC0gcmVnc3Vic2V0cyhNTEEgfi4sIGRhdGEgPSBtbGEubG0uZGF0YS5jdHJkLCBudm1heCA9IDE2LCAgbWV0aG9kID0gImJhY2t3YXJkIiApDQpCZXN0U3Vic2V0c1JlZyhtbGEuYmVzdC5zdWJzZXRzLmN0cmQpDQpgYGANCg0KDQpgYGB7cn0NCnByZWQudmFyLmN0cmQgPC0gbmFtZXMoY29lZihtbGEuYmVzdC5zdWJzZXRzLmN0cmQsNykpWy0oMTozKV0NCmFjdXRhbC52YXIuY3RyZCA8LWMoInJhY2UiLCAibWFqb3IiLCBwcmVkLnZhci5jdHJkKQ0KZm9ybXVsYS5zdHIuY3RyZCA8LSBwYXN0ZSgiTUxBIiwgIn4iLCBwYXN0ZShhY3V0YWwudmFyLmN0cmQsIGNvbGxhcHNlID0gIiArICIpKQ0KTUxBLm1vZGVsLmZvcm11bGEgPC0gYXMuZm9ybXVsYShmb3JtdWxhLnN0ci5jdHJkKQ0KTUxBLm1vZGVsLmN0cmQgPC0gbG0oTUxBLm1vZGVsLmZvcm11bGEgLCBkYXRhID0gbWxhLmxtLmRhdGEuY3RyZCkNCnN1bW1hcnkoTUxBLm1vZGVsLmN0cmQpJGNvZWYNCmBgYA0KDQoNCg0KDQpgYGB7cn0NCiMjIyBCb290c3RyYXAgY29uZmlkZW5jZSBpbnRlcnZhbHMNCmJvb3QuY29lZi5tbGEuY3RyZCA8LSBmdW5jdGlvbihkYXRhLCBpbmRpY2VzKSB7DQogIGQgPC0gZGF0YVtpbmRpY2VzLCBdICAjIHJlc2FtcGxlIHJvd3MNCiAgZml0IDwtIGxtKE1MQS5tb2RlbC5mb3JtdWxhICwgZGF0YSA9IGQpDQogIHJldHVybihjb2VmKGZpdCkpICAgICAgIyByZXR1cm4gY29lZmZpY2llbnRzDQp9DQpgYGANCg0KDQpgYGB7cn0NCiMgUGVyZm9ybSBib290c3RyYXAgKFIgPSBudW1iZXIgb2YgcmVzYW1wbGVzKQ0Kc2V0LnNlZWQoMzEyKSAgIyBmb3IgcmVwcm9kdWNpYmlsaXR5DQpib290LnJlc3VsdHMuY3RyZCA8LSBib290KG1sYS5sbS5kYXRhLmN0cmQsIGJvb3QuY29lZi5tbGEuY3RyZCwgUiA9IDEwMDApDQpgYGANCg0KYGBge3J9DQphbGwuY3RyZC5jaXMgPC0gZ2V0LmFsbC5ib290LmNpcyhib290LnJlc3VsdHMuY3RyZCApDQpJbmZlcmVuY2VUYWJsZSA8LSByb3VuZChjYmluZChzdW1tYXJ5KE1MQS5tb2RlbC5jdHJkKSRjb2VmLCBhbGwuY3RyZC5jaXMgKSw0KQ0KcHJpbnQoSW5mZXJlbmNlVGFibGUpIA0KYGBgDQoNCg0KVGhlIG92ZXJhbGwgbW9kZWwgd2FzIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQsIGluZGljYXRpbmcgdGhhdCB0aGUgc2V0IG9mIHByZWRpY3RvcnMgbWVhbmluZ2Z1bGx5IGV4cGxhaW5lZCB2YXJpYW5jZSBpbiBtYXRoIGxlYXJuaW5nIGFueGlldHkuDQoNCkFtb25nIGRlbW9ncmFwaGljIHZhcmlhYmxlcywgKipyYWNlKiogd2FzIGEgc2lnbmlmaWNhbnQgcHJlZGljdG9yLiBTcGVjaWZpY2FsbHksIEJsYWNrIHN0dWRlbnRzIHJlcG9ydGVkIHNpZ25pZmljYW50bHkgaGlnaGVyIGFueGlldHkgdGhhbiB0aGUgcmVmZXJlbmNlIEFzaWFuIGdyb3VwICgkXGJldGEgPSAwLjM0LCBwID0gLjA0MyQpLCB3aGVyZWFzIHN0dWRlbnRzIGlkZW50aWZ5aW5nIGFzIFdoaXRlIG9yIE90aGVyIHJhY2lhbCBncm91cHMgZGlkIG5vdCBkaWZmZXIgc2lnbmlmaWNhbnRseSBmcm9tIHRoZSByZWZlcmVuY2UgZ3JvdXAgKCRwID4gLjA1JCkuIEFkZGl0aW9uYWxseSwgc3R1ZGVudHMgbWFqb3JpbmcgaW4gKipTVEVNKiogZmllbGRzIHJlcG9ydGVkIHNpZ25pZmljYW50bHkgbG93ZXIgYW54aWV0eSBjb21wYXJlZCB0byB0aG9zZSBvdXRzaWRlIFNURU0gbWFqb3JzICgkXGJldGEgPSDiiJIwLjE3LCBwID0gLjAzOSQpLiBBY2FkZW1pYyAqKm1ham9ycyoqIGNhdGVnb3JpemVkIGFzIEhlYWx0aCBvciBPdGhlciBkaWQgbm90IHNob3cgc2lnbmlmaWNhbnQgcmVsYXRpb25zaGlwcyB3aXRoIGFueGlldHkgKCRwID4gLjA1JCkuDQoNClBzeWNob2xvZ2ljYWwgYW5kIGluc3RydWN0aW9uYWwgZmFjdG9ycyBkZW1vbnN0cmF0ZWQgbm90YWJsZSBhc3NvY2lhdGlvbnMgd2l0aCBtYXRoIGxlYXJuaW5nIGFueGlldHkuIEhpZ2hlciBsZXZlbHMgb2YgKipzZWxmLWVmZmljYWN5Kiogd2VyZSBzdHJvbmdseSBhc3NvY2lhdGVkIHdpdGggbG93ZXIgYW54aWV0eSAoJFxiZXRhID0g4oiSMC4zOSwgcCA8IC4wMDEkKSwgcmVwcmVzZW50aW5nIHRoZSBsYXJnZXN0IGVmZmVjdCBpbiB0aGUgbW9kZWwuIE1vcmUgZnJlcXVlbnQgdXNlIG9mIHRlY2hub2xvZ3ktc3VwcG9ydGVkIGxlYXJuaW5nICgkXGJldGEgPSDiiJIwLjEwLCBwIDwgLjAwMSQpIGFuZCAqKnRlYWNoZXItY2VudGVyZWQqKiBhcHByb2FjaGVzICgkXGJldGEgPSDiiJIwLjE4LCBwIDwgLjAwMSQpIHdpbGwgaGVscCByZWR1Y2UgYW54aWV0eSBsZXZlbHMuIEluIGNvbnRyYXN0LCBpbmNyZWFzZWQgcmVsaWFuY2Ugb24gKipyZXNvdXJjZS1iYXNlZCBsZWFybmluZyoqIHN0cmF0ZWdpZXMgd2FzIHBvc2l0aXZlbHkgYXNzb2NpYXRlZCB3aXRoIGFueGlldHkgKCRcYmV0YSA9IDAuMDksIHAgPSAuMDExJCkuIEFsdGhvdWdoICoqc3R1ZGVudC1jZW50ZXJlZCoqIGluc3RydWN0aW9uIHNob3dlZCBhIHBvc2l0aXZlIGFzc29jaWF0aW9uIHdpdGggYW54aWV0eSwgdGhpcyBlZmZlY3QgZGlkIG5vdCByZWFjaCBzdGF0aXN0aWNhbCBzaWduaWZpY2FuY2UgKCRcYmV0YSA9IDAuMDYsIHAgPSAuMDc0JCkuDQoNClRvZ2V0aGVyLCB0aGVzZSByZXN1bHRzIGRlbW9uc3RyYXRlIHRoYXQgY29uZmlkZW5jZSBpbiBvbmXigJlzIG1hdGhlbWF0aWNhbCBhYmlsaXR5IGFuZCBzcGVjaWZpYyBpbnN0cnVjdGlvbmFsIG1ldGhvZHMgcGxheSBhbiBpbXBvcnRhbnQgcm9sZSBpbiBzaGFwaW5nIHN0dWRlbnRz4oCZIG1hdGggbGVhcm5pbmcgYW54aWV0eS4gQXBwcm9hY2hlcyB0aGF0IHByb3ZpZGUgc3RydWN0dXJlZCBndWlkYW5jZeKAlHN1Y2ggYXMgdGVhY2hlci1jZW50ZXJlZCBkZWxpdmVyeSBhbmQgdGVjaG5vbG9neSBpbnRlZ3JhdGlvbuKAlGFwcGVhciB0byByZWR1Y2UgYW54aWV0eSwgd2hlcmVhcyBncmVhdGVyIGVtcGhhc2lzIG9uIGluZGVwZW5kZW50IHJlc291cmNlLWJhc2VkIGxlYXJuaW5nIG1heSBjb250cmlidXRlIHRvIGluY3JlYXNlZCBhbnhpZXR5Lg0KDQoNCiMgU3RydWN0dXJhbCBFcXVhdGlvbiBNb2RlbGluZyBBcHByb2FjaA0KDQoqKlN0cnVjdHVyYWwgZXF1YXRpb24gbW9kZWxpbmcgKFNFTSkqKiBpcyBhIGxpbmVhciBtb2RlbCBmcmFtZXdvcmsgdGhhdCBtb2RlbHMgYm90aCBzaW11bHRhbmVvdXMgcmVncmVzc2lvbiBlcXVhdGlvbnMgd2l0aCBsYXRlbnQgdmFyaWFibGVzLiAgTW9kZWxzIHN1Y2ggYXMgbGluZWFyIHJlZ3Jlc3Npb24sIG11bHRpdmFyaWF0ZSByZWdyZXNzaW9uLCBwYXRoIGFuYWx5c2lzLCBjb25maXJtYXRvcnkgZmFjdG9yIGFuYWx5c2lzLCBhbmQgc3RydWN0dXJhbCByZWdyZXNzaW9uIGNhbiBiZSB0aG91Z2h0IG9mIGFzIHNwZWNpYWwgY2FzZXMgb2YgU0VNLiBUaGUgZm9sbG93aW5nIHJlbGF0aW9uc2hpcHMgYXJlIHBvc3NpYmxlIGluIFNFTToNCg0KKiAqb2JzZXJ2ZWQgdG8gb2JzZXJ2ZWQgdmFyaWFibGVzKiAoJFxnYW1tYSQsIGUuZy4sIHJlZ3Jlc3Npb24pDQoqICpsYXRlbnQgdG8gb2JzZXJ2ZWQgdmFyaWFibGVzKiAoJFxsYW1iZGEkLCBlLmcuLCBjb25maXJtYXRvcnkgZmFjdG9yIGFuYWx5c2lzKQ0KKiAqbGF0ZW50IHRvIGxhdGVudCB2YXJpYWJsZXMqICgkXGdhbW1hLCBcYmV0YSQsIGUuZy4sIHN0cnVjdHVyYWwgcmVncmVzc2lvbikNCiANClNFTSB1bmlxdWVseSBlbmNvbXBhc3NlcyBib3RoIG1lYXN1cmVtZW50IGFuZCBzdHJ1Y3R1cmFsIG1vZGVscy4gVGhlIG1lYXN1cmVtZW50IG1vZGVsIHJlbGF0ZXMgb2JzZXJ2ZWQgdG8gbGF0ZW50IHZhcmlhYmxlcyBhbmQgdGhlIHN0cnVjdHVyYWwgbW9kZWwgcmVsYXRlcyBsYXRlbnQgdG8gbGF0ZW50IHZhcmlhYmxlcy4gDQoNCg0KIyMgTm90YXRpb25zIGFuZCBUZWNobmljYWwgVGVybXMgaW4gU0VNDQoNCg0KDQoqKlNvbWUgVGVjaG5pY2FsIFRlcm1zIGluIFNFTSoqOg0KDQoqICoqb2JzZXJ2ZWQgdmFyaWFibGUqKjogYSB2YXJpYWJsZSB0aGF0IGV4aXN0cyBpbiB0aGUgZGF0YSwgYS5rLmEgaXRlbSBvciBtYW5pZmVzdCB2YXJpYWJsZQ0KDQoqICoqbGF0ZW50IHZhcmlhYmxlKio6IGEgdmFyaWFibGUgdGhhdCBpcyBjb25zdHJ1Y3RlZCBhbmQgZG9lcyBub3QgZXhpc3QgaW4gdGhlIGRhdGENCg0KKiAqKmV4b2dlbm91cyB2YXJpYWJsZSoqOiBhbiBpbmRlcGVuZGVudCB2YXJpYWJsZSBlaXRoZXIgb2JzZXJ2ZWQgKHgpIG9yIGxhdGVudCAoJFx4aSQpIHRoYXQgZXhwbGFpbnMgYW4gZW5kb2dlbm91cyB2YXJpYWJsZQ0KDQoqICoqZW5kb2dlbm91cyB2YXJpYWJsZSoqOiBhIGRlcGVuZGVudCB2YXJpYWJsZSwgZWl0aGVyIG9ic2VydmVkICh5KSBvciBsYXRlbnQgKCRcZXRhJCkgdGhhdCBoYXMgYSBjYXVzYWwgcGF0aCBsZWFkaW5nIHRvIGl0DQoNCiogKiptZWFzdXJlbWVudCBtb2RlbCoqOiBhIG1vZGVsIHRoYXQgbGlua3Mgb2JzZXJ2ZWQgdmFyaWFibGVzIHdpdGggbGF0ZW50IHZhcmlhYmxlcw0KDQoqICoqaW5kaWNhdG9yKio6IGFuIG9ic2VydmVkIHZhcmlhYmxlIGluIGEgbWVhc3VyZW1lbnQgbW9kZWwgKGNhbiBiZSBleG9nZW5vdXMgb3IgZW5kb2dlbm91cykNCg0KKiAqKmZhY3RvcioqOiBhIGxhdGVudCB2YXJpYWJsZSBkZWZpbmVkIGJ5IGl0cyBpbmRpY2F0b3JzIChjYW4gYmUgZXhvZ2Vub3VzIG9yIGVuZG9nZW5vdXMpDQoNCiogKipsb2FkaW5nKio6IGEgcGF0aCBiZXR3ZWVuIGFuIGluZGljYXRvciBhbmQgYSBmYWN0b3INCg0KKiAqKnN0cnVjdHVyYWwgbW9kZWwqKjogYSBtb2RlbCB0aGF0IHNwZWNpZmllcyBjYXVzYWwgcmVsYXRpb25zaGlwcyBhbW9uZyBleG9nZW5vdXMgdmFyaWFibGVzIHRvIGVuZG9nZW5vdXMgdmFyaWFibGVzIChjYW4gYmUgb2JzZXJ2ZWQgb3IgbGF0ZW50KQ0KDQoqICoqcmVncmVzc2lvbiBwYXRoKio6IGEgcGF0aCBiZXR3ZWVuIGV4b2dlbm91cyBhbmQgZW5kb2dlbm91cyB2YXJpYWJsZXMgKGNhbiBiZSBvYnNlcnZlZCBvciBsYXRlbnQpDQoNCg0KDQojIyBTRU0gUGF0aCBNb2RlbA0KDQpBIHBhdGggbW9kZWwgc2VydmVzIGFzIHRoZSB2aXN1YWwgYW5kIG1hdGhlbWF0aWNhbCBibHVlcHJpbnQgZm9yIGEgU3RydWN0dXJhbCBFcXVhdGlvbiBNb2RlbCAoU0VNKS4gVGhpcyBkaWFncmFtIGVtcGxveXMgYSBzdGFuZGFyZGl6ZWQgbm90YXRpb24gdG8gcmVwcmVzZW50IGh5cG90aGVzaXplZCByZWxhdGlvbnNoaXBzIGJldHdlZW4gdmFyaWFibGVzLiBUaGUgc3BlY2lmaWMgbW9kZWwgdG8gYmUgdGVzdGVkLCB3aGljaCBleGFtaW5lcyB0aGUgY29tcGxleCBzdHJ1Y3R1cmFsIHJlbGF0aW9uc2hpcHMgYmV0d2VlbiBlbmRvZ2Vub3VzIGFuZCBleG9nZW5vdXMgdmFyaWFibGVzLCBoYXMgdGhlIGZvbGxvd2luZyBzdHJ1Y3R1cmU6DQoNCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBvdXQud2lkdGg9IjcwJSJ9DQppbmNsdWRlX2dyYXBoaWNzKCJIeXBvdGhldGljYWxTRU0ucG5nIikNCmBgYA0KDQpUbyBiZXR0ZXIgdW5kZXJzdGFuZCB0aGUgYWR2YW50YWdlcyBhbmQgZGlzYWR2YW50YWdlcyBvZiBTdHJ1Y3R1cmFsIEVxdWF0aW9uIE1vZGVsaW5nIChTRU0pIGZvciBhbmFseXppbmcgY29tcGxleCByZWxhdGlvbnNoaXBz4oCUc3VjaCBhcyB0aG9zZSBiZXR3ZWVuIGxhdGVudCB2YXJpYWJsZXMgbGlrZSBtYXRoIGV2YWx1YXRpb24gYW5kIGxlYXJuaW5nIGFueGlldHkuIHdlIHdpbGwgYnJpZWZseSBkZXNjcmliZSBpdHMgbWF0aGVtYXRpY2FsIGZvcm11bGF0aW9uIGFuZCBNTEUgb2YgYWxsIG1vZGVsIHBhcmFtZXRlcnMgdXNpbmcgdGhlIGFib3ZlIGh5cG90aGV0aWNhbCBTRU0gcGF0aCBtb2RlbCBpbiB0aGUgYXBwZW5kaXguDQoNCg0KDQojIyBTRU0gSW1wbGVtZW50YXRpb24NCg0KV2UgdXNlIHRoZSBSIGBsYXZhYW5gIGxpYnJhcnkgdG8gaW1wbGVtZW50IHRoZSBTRU0gdG8gYXNzZXNzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBtYXRoIGV2YWx1YXRpb24sIGxlYXJuaW5nIGFueGlldHksIGFuZCByZWxhdGVkIGV4b2dlbm91cyB2YXJpYWJsZXMuIFRoZSBvdXRwdXQgcHJlc2VudHMgcmVzdWx0cyBiYXNlZCBvbiBzdGFuZGFyZGl6ZWQgdmFyaWFibGVzLiBUaGUgaW50ZXJwcmV0YXRpb24gb2YgdGhlIHJlZ3Jlc3Npb24gY29lZmZpY2llbnRzIGlzIHNpbWlsYXIgdG8gdGhhdCBpbiBhIHJlZ3VsYXIgcmVncmVzc2lvbiBtb2RlbCwgaW5kaWNhdGluZyB0aGUgY2hhbmdlIGluIHRoZSBvdXRjb21lIChpbiBzdGFuZGFyZCBkZXZpYXRpb25zKSBmb3IgYSBvbmUtc3RhbmRhcmQtZGV2aWF0aW9uIGluY3JlYXNlIGluIGEgcHJlZGljdG9yLiANCg0KDQoqKlF1aWNrIFJlZmVyZW5jZSBvZiBgbGF2YWFuYCBTeW50YXgqKg0KDQoqIGB+IHByZWRpY3RgLCB1c2VkIGZvciByZWdyZXNzaW9uIG9mIG9ic2VydmVkIG91dGNvbWUgdG8gb2JzZXJ2ZWQgcHJlZGljdG9ycyAoZS5nLiwgeSB+IHgpDQoqIGAxPX4gaW5kaWNhdG9yMWAsIHVzZWQgZm9yIGxhdGVudCB2YXJpYWJsZSB0byBvYnNlcnZlZCBpbmRpY2F0b3IgaW4gZmFjdG9yIGFuYWx5c2lzIG1lYXN1cmVtZW50IG1vZGVscyAoZS5nLiwgYGYgPX4gcSArIHIgKyBzYCkNCiogYGB+fmAgY292YXJpYW5jZSAoZS5nLiwgYHggfn4geGApDQoqIGB+MWAgaW50ZXJjZXB0IG9yIG1lYW4gKGUuZy4sIGB4IH4gMWAgZXN0aW1hdGVzIHRoZSBtZWFuIG9mIHZhcmlhYmxlIHgpDQoqIGAxKmAgZml4ZXMgcGFyYW1ldGVyIG9yIGxvYWRpbmcgdG8gb25lIChlLmcuLCBgZiA9fiAxKnFgKQ0KKiBgTkEqYCBmcmVlcyBwYXJhbWV0ZXIgb3IgbG9hZGluZyAodXNlZnVsIHRvIG92ZXJyaWRlIGRlZmF1bHQgbWFya2VyIG1ldGhvZCwgKGUuZy4sIGBmID1+IE5BKnFgKQ0KKiBgYSpgIGxhYmVscyB0aGUgcGFyYW1ldGVyIOKAmGHigJksIHVzZWQgZm9yIG1vZGVsIGNvbnN0cmFpbnRzIChlLmcuLCBgZiA9fiBhKnFgKQ0KDQoNCg0KYGBge3J9DQpBbnhpZXR5Lm1lYSA8LSBDb21wLkFueGlldHlbLCBjKCJBTUFTLjIiLCAiQU1BUy40IiwgIkFNQVMuNSIsICAiQU1BUy44IildDQpBbnhpZXR5Lm1sYSA8LSBDb21wLkFueGlldHlbLCBjKCJBTUFTLjEiLCAiQU1BUy4zIiwgIkFNQVMuNiIsICJBTUFTLjciLCAiQU1BUy45IildDQpuYW1lcyhBbnhpZXR5Lm1lYSkgPC0gYygiTUVBMiIsICJNRUE0IiwgIk1FQTUiLCAgIk1FQTgiKSAgDQpuYW1lcyhBbnhpZXR5Lm1sYSkgPC0gYygiTUxBMSIsICJNTEEzIiwgIk1MQTYiLCAiTUxBNyIsICJNTEE5IikNCmZhY3Rvci5uYW1lcyA8LSBjKCJUZWNobm9sb2d5Lnd0LnBjYSIsICJTZWxmRWZmaWNhY3kud3QucGNhIiwgIkVuZ2FnZS53dC5wY2EiLCAic2V4IiwNCiAgICAgICAgICAgICAgICAgICJUZWFjaGVyLmN0cmQud3QucGNhIiwgIlN0dWRlbnQuY3RyZC53dC5wY2EiLCAiUmVzb3VyY2Uud3QucGNhIikNCiMjDQpmYWN0b3IudmFyIDwtIEFueGlldHkuQW5hbHl0aWMuRGF0YVssIGZhY3Rvci5uYW1lc10NCm5hbWVzKGZhY3Rvci52YXIpIDwtIGMoIlRlY2giLCAiRWZmaWNhY3kiLCAiRW5nYWdlIiwgImdlbmRlciIsDQogICAgICAgICAgICAgICAgICAiVGVhY2hlci5jdHJkIiwgIlN0dWRlbnQuY3RyZCIsICJSZXNvdXJjZSIpDQoNCiMjIyBzdHJhdGVnaWVzIHZhcg0Kc3RyYXRneS52YXIgPC1jKCJDb29wb3JhdGl2ZS53dC5wY2EiLCAiRGVkdWN0aXZlLnd0LnBjYSIsICJEZW1vbnN0cmF0aW9uLnd0LnBjYSIsICJJbmR1Y3RpdmUud3QucGNhIiwiSW50ZWdyYXRpdmUud3QucGNhIiAsIkxlY3R1cmVUeXBlLnd0LnBjYSIsICJSZXBldGl0aXZlLnd0LnBjYSIgKQ0Kc3RyYXRlZ3kubmFtZSA8LSBjKCJDb29wIiwgIkRlZHVjIiwgIkRlbW9uIiwgIkluZHVjIiwiSW50ZWciICwiTGVjdCIsICJSZXBldCIgKQ0KdGVhY2hpbmdzdHJhdGVneSA8LSBBbnhpZXR5LkFuYWx5dGljLkRhdGFbLCBzdHJhdGd5LnZhcl0NCm5hbWVzKHRlYWNoaW5nc3RyYXRlZ3kpIDwtIHN0cmF0ZWd5Lm5hbWUgDQpTRU0uZGF0YSA8LSBjYmluZChBbnhpZXR5Lm1lYSwgQW54aWV0eS5tbGEsIGZhY3Rvci52YXIsdGVhY2hpbmdzdHJhdGVneSApDQoNCiMjIyAgU0VNIG1vZGVscw0KDQpTRU1Nb2RlbCA8LQ0KJyBFdmFsLkFueGlldHkgPX4gIE1FQTIgKyBNRUE0ICsgTUVBNSArIE1FQTggICMjIG1lYXN1cmVtZW50IG1vZGVsIGZvciBFdmFsLkFueGlldHkNCiAgTGVhcm4uQW54aWV0eSA9fiBNTEExICsgTUxBMyArIE1MQTYgKyBNTEE3ICsgTUxBOSAgICMjIG1lYXN1cmVtZW50IG1vZGVsIGZvciBMZWFybi5BbnhpZXR5IA0KICBUZWFjaGVyQ3RyZCA9fiBEZWR1YyArIExlY3QgKyBEZW1vbiArIFJlcGV0ICAjIFRlYWNoZXIgY2VudGVyZWQNCiAgU3R1ZGVudEN0cmQgPX4gQ29vcCArIEluZHVjICsgSW50ZWcgICMgU3R1ZGVudCBjZW50ZXJlZA0KICBFdmFsLkFueGlldHkgfiBUZWNoICsgRWZmaWNhY3kgKyBFbmdhZ2UgKyBnZW5kZXIgKyBUZWFjaGVyQ3RyZCArIFN0dWRlbnRDdHJkICsgUmVzb3VyY2UgICAgIyMgRXZhbC5BbnhpZXR5IGFzIGFuIG91dGNvbWUNCiAgTGVhcm4uQW54aWV0eSB+IFRlY2ggKyBFZmZpY2FjeSArIEVuZ2FnZSArIGdlbmRlciArIFRlYWNoZXJDdHJkKyBTdHVkZW50Q3RyZCArIFJlc291cmNlICAgICMjIExlYXJuLkFueGlldHkgYXMgYW4gb3V0Y29tZQ0KICBFdmFsLkFueGlldHkgfn4gTGVhcm4uQW54aWV0eSAgICAgIyMgY29ycmVsYXRpb24gYmV0d2VlbiBFdmFsLkFueGlldHkgYW5kIExlYXJuLkFueGlldHkgDQonDQogDQpvdXRwdXQgPC0gc2VtKG1vZGVsID0gU0VNTW9kZWwsIGRhdGEgPSBTRU0uZGF0YSwgc3RkLmx2ID0gVFJVRSwNCiAgICAgICAgICAgICAgbWlzc2luZyA9ICJmaW1sIiwgbWltaWMgPSAiTXBsdXMiKQ0KcmVzdWx0cyA8LSBzdW1tYXJ5KG91dHB1dCwgc3RhbmRhcmRpemVkID0gVFJVRSwgZml0Lm1lYXN1cmVzID0gVFJVRSkNCg0KYGBgDQoNClRoZSBjb21wb25lbnQgcmVncmVzc2lvbiBhbnMgbGF0ZW50IG1vZGVscyBpbiB0aGUgU0VNIGFyZSBzcGVjaWZpZWQgaW4gdGhlIGZvbGxvd2luZy4NCg0KYGBgDQogICMjIG1lYXN1cmVtZW50IG1vZGVsIGZvciBFdmFsLkFueGlldHkNCiAgRXZhbC5BbnhpZXR5ID1+ICBNRUEyICsgTUVBNCArIE1FQTUgKyBNRUE4ICAgICAgICAgICAgDQogICMjIG1lYXN1cmVtZW50IG1vZGVsIGZvciBMZWFybi5BbnhpZXR5IA0KICBMZWFybi5BbnhpZXR5ID1+IE1MQTEgKyBNTEEzICsgTUxBNiArIE1MQTcgKyBNTEE5ICANCiAgIyBMYXRlbnQgcmVncmVzc2lvbiBvZiB0ZWFjaGluZyBTdHJhdGVnaWVzDQogIFRlYWNoZXJDdHJkID1+IERlZHVjICsgTGVjdCArIERlbW9uICsgUmVwZXQgICMgVGVhY2hlciBjZW50ZXJlZA0KICBTdHVkZW50Q3RyZCA9fiBDb29wICsgSW5kdWMgKyBJbnRlZyAgIyBTdHVkZW50IGNlbnRlcmVkDQogICMjIEV2YWwuQW54aWV0eSBhcyBhbiBvdXRjb21lDQogIEV2YWwuQW54aWV0eSB+IFRlY2ggKyBFZmZpY2FjeSArIEVuZ2FnZSArIGdlbmRlciArIFRlYWNoZXIuY3RyZCArIFN0dWRlbnQuY3RyZCArIFJlc291cmNlICsgcmFjZSAgIA0KICAjIyBMZWFybi5BbnhpZXR5IGFzIGFuIG91dGNvbWUNCiAgTGVhcm4uQW54aWV0eSB+IFRlY2ggKyBFZmZpY2FjeSArIEVuZ2FnZSArIGdlbmRlciArIFRlYWNoZXIuY3RyZCArIFN0dWRlbnQuY3RyZCArIFJlc291cmNlICsgcmFjZSAgDQogIEV2YWwuQW54aWV0eSB+fiBMZWFybi5BbnhpZXR5ICAgICAjIyBjb3JyZWxhdGlvbiBiZXR3ZWVuIEV2YWwuQW54aWV0eSBhbmQgTGVhcm4uQW54aWV0eSANCmBgYA0KDQpUaGUga2V5IGdvb2RuZXNzLW9mLWZpdCBzdGF0aXN0aWNzIGFuZCBlc3RpbWF0ZWQgcGFyYW1ldGVycyBhcmUgc3VtbWFyaXplZCBpbiB0aGUgZm9sbG93aW5nLg0KDQoNCmBgYHtyfQ0KaW50ZXJwcmV0X2ZpdCA8LSBmdW5jdGlvbihmaXRfb2JqKSB7DQogIG1lYXN1cmVzIDwtIGZpdE1lYXN1cmVzKGZpdF9vYmopDQogIA0KICAjY2F0KCI9PT0gU0VNIE1PREVMIEZJVCBBU1NFU1NNRU5UID09PVxuIikNCiAgY2F0KHNwcmludGYoIkNoaS1TcXVhcmU6IM+HwrIoJWQpID0gJS4yZiwgcCA9ICUuM2ZcbiIsIA0KICAgICAgICAgICAgICBtZWFzdXJlc1siZGYiXSwgbWVhc3VyZXNbImNoaXNxIl0sIG1lYXN1cmVzWyJwdmFsdWUiXSkpDQogIGNhdChzcHJpbnRmKCJDRkk6ICUuM2YgJXNcbiIsIG1lYXN1cmVzWyJjZmkiXSwNCiAgICAgICAgICAgICAgaWZlbHNlKG1lYXN1cmVzWyJjZmkiXSA+PSAwLjk1LCAiKEV4Y2VsbGVudCkiLA0KICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKG1lYXN1cmVzWyJjZmkiXSA+PSAwLjkwLCAiKEFjY2VwdGFibGUpIiwgIihQb29yKSIpKSkpDQogIGNhdChzcHJpbnRmKCJUTEk6ICUuM2YgJXNcbiIsIG1lYXN1cmVzWyJ0bGkiXSwNCiAgICAgICAgICAgICAgaWZlbHNlKG1lYXN1cmVzWyJ0bGkiXSA+PSAwLjk1LCAiKEV4Y2VsbGVudCkiLA0KICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKG1lYXN1cmVzWyJ0bGkiXSA+PSAwLjkwLCAiKEFjY2VwdGFibGUpIiwgIihQb29yKSIpKSkpDQogIGNhdChzcHJpbnRmKCJSTVNFQTogJS4zZiBbOTAlJSBDSTogJS4zZiwgJS4zZl0gJXNcbiIsIA0KICAgICAgICAgICAgICBtZWFzdXJlc1sicm1zZWEiXSwgbWVhc3VyZXNbInJtc2VhLmNpLmxvd2VyIl0sIG1lYXN1cmVzWyJybXNlYS5jaS51cHBlciJdLA0KICAgICAgICAgICAgICBpZmVsc2UobWVhc3VyZXNbInJtc2VhIl0gPD0gMC4wNiwgIihFeGNlbGxlbnQpIiwNCiAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShtZWFzdXJlc1sicm1zZWEiXSA8PSAwLjA4LCAiKEFjY2VwdGFibGUpIiwgIihQb29yKSIpKSkpDQogIGNhdChzcHJpbnRmKCJTUk1SOiAlLjNmICVzXG4iLCBtZWFzdXJlc1sic3JtciJdLA0KICAgICAgICAgICAgICBpZmVsc2UobWVhc3VyZXNbInNybXIiXSA8PSAwLjA4LCAiKEV4Y2VsbGVudCkiLA0KICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKG1lYXN1cmVzWyJzcm1yIl0gPD0gMC4xMCwgIihBY2NlcHRhYmxlKSIsICIoUG9vcikiKSkpKQ0KfQ0KDQojIyMNCnJlcG9ydF9zZW0gPC0gZnVuY3Rpb24oZml0LCBtb2RlbF9uYW1lID0gIlRoZSBTRU0iKSB7DQogIA0KICAjIEZpdCBtZWFzdXJlcw0KICBmaXRfbWVhcyA8LSBmaXRNZWFzdXJlcyhmaXQsIGMoImNoaXNxIiwgImRmIiwgInB2YWx1ZSIsICJjZmkiLCAidGxpIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJybXNlYSIsICJybXNlYS5jaS5sb3dlciIsICJybXNlYS5jaS51cHBlciIsICJzcm1yIikpDQogIA0KICAjIFBhcmFtZXRlcnMNCiAgcGFyYW1zIDwtIHBhcmFtZXRlckVzdGltYXRlcyhmaXQpDQogIHN0ZF9wYXJhbXMgPC0gc3RhbmRhcmRpemVkU29sdXRpb24oZml0KQ0KICANCiAgY2F0KCI9PT0gU1RSVUNUVVJBTCBFUVVBVElPTiBNT0RFTElORyBSRVNVTFRTID09PVxuXG4iKQ0KICBjYXQoIk1PREVMIEZJVDpcbiIpDQogIA0KICAjIFVzZSB0aGUgZnVuY3Rpb24NCiAgaW50ZXJwcmV0X2ZpdChvdXRwdXQpDQogIGNhdCgiXG5cbiIpDQogICMgU2lnbmlmaWNhbnQgc3RydWN0dXJhbCBwYXRocw0KICBzaWdfcGF0aHMgPC0gc3RkX3BhcmFtc1tzdGRfcGFyYW1zJG9wID09ICJ+IiAmIHN0ZF9wYXJhbXMkcHZhbHVlIDwgMC4xLCBdDQogIGlmIChucm93KHNpZ19wYXRocykgPiAwKSB7DQogICAgY2F0KCJTSUdOSUZJQ0FOVCBTVFJVQ1RVUkFMIFBBVEhTOlxuIikNCiAgICBmb3IgKGkgaW4gMTpucm93KHNpZ19wYXRocykpIHsNCiAgICAgIGNhdChzcHJpbnRmKCItICVzIOKGkiAlczogzrIgPSAlLjJmLCBwID0gJS4zZlxuIiwNCiAgICAgICAgICAgICAgICAgIHNpZ19wYXRocyRyaHNbaV0sIHNpZ19wYXRocyRsaHNbaV0sDQogICAgICAgICAgICAgICAgICBzaWdfcGF0aHMkZXN0W2ldLCBzaWdfcGF0aHMkcHZhbHVlW2ldKSkNCiAgICB9DQogICAgY2F0KCJcbiIpDQogIH0NCiAgDQogICMgZmFjdG9yIGxvYWRpbmcgZm9yIGxhdGVudCB2YXJpYWJsZXMNCiAgY2F0KCJcblxuRkFDVE9SIExPQURJTkdTXG5cbiIpDQogIA0KICBwcmludChzdGRfcGFyYW1zW3N0ZF9wYXJhbXMkb3AgPT0gIj1+IiwgXSkNCiAgDQogICMjIyMjDQogICMgUi1zcXVhcmVkDQogIHIyIDwtIGluc3BlY3QoZml0LCAicjIiKQ0KICBpZiAobGVuZ3RoKHIyKSA+IDApIHsNCiAgICBjYXQoIlZBUklBTkNFIEVYUExBSU5FRCAoUsKyKTpcblxuIikNCiAgICBmb3IgKGkgaW4gMTpsZW5ndGgocjIpKSB7DQogICAgICBjYXQoc3ByaW50ZigiLSAlczogJS4xZiUlXG4iLCBuYW1lcyhyMilbaV0sIHIyW2ldICogMTAwKSkNCiAgICB9DQogIH0NCiAgDQogICMjIFJlZ3Jlc3Npb24gY29lZmZpY2llbnRzDQogIA0KICBjYXQoIlxuXG5DT0VGRklDSUVOVFMgT0YgUkVHUkVTU0lPTlxuXG4iKQ0KICANCiAgcHJpbnQoc3RkX3BhcmFtc1tzdGRfcGFyYW1zJG9wID09ICJ+IiwgXSkNCiAgDQogICAgICMgQ292YXJpYW5jZSBiZXR3ZWVuIE1hdGggQW54aWV0aWVzDQogICAgICAjcGFyYW1fZXN0IDwtIHBhcmFtZXRlckVzdGltYXRlcyhmaXQpDQogICAgIGNvdl9sYXRlbnQgPC0gc3RkX3BhcmFtc1sNCiAgICAgICAgICAgICAgc3RkX3BhcmFtcyRsaHMgPT0gIk1hdGhFdmFsIiAmIA0KICAgICAgICAgICAgICBzdGRfcGFyYW1zJHJocyA9PSAiTGVhcm5BbngiICYgDQogICAgICAgICAgICAgIHN0ZF9wYXJhbXMkb3AgPT0gIn5+IiwNCiAgICAgICAgICBdDQogICAgICMjIw0KICAgICBjYXQoIlxuXG5DT1ZBUklBTkNFIDpcbiIpDQogICAgIGxhdGVudF9jb3ZfbWF0cml4IDwtIGxhdkluc3BlY3QoZml0LCAiZXN0IikkcHNpDQogICAgIGNvdl9vdXQgPC0gbGF0ZW50X2Nvdl9tYXRyaXhbIkxlYXJuLkFueGlldHkiLCAiRXZhbC5BbnhpZXR5Il0NCiAgICAgY2F0KCItIExlYXJuLkFueGlldHkgYW5kIEV2YWwuQW54aWV0eToiLCBjb3Zfb3V0KQ0KfQ0KDQojIFVzZSB0aGUgZnVuY3Rpb24NCnJlcG9ydF9zZW0ob3V0cHV0LCAiTWF0aCBBbnhpZXR5IikNCmBgYA0KDQpUaGUgcmVncmVzc2lvbiBjb2VmZmljaWVudHMgYW5kIGZhY3RvciBsb2FkaW5ncyBpbiB0aGUgYWJvdmUgdGFibGUgYXJlIHN1bW1hcml6ZWQgaW4gdGhlIGZvbGxvd2luZyBTRU0gcGF0aCBkaWFncmFtIGdlbmVyYXRlZCB1c2luZyBgbGF2YWFuUGxvdGAgZnVuY3Rpb24uICANCg0KYGBge3J9DQpsYXZhYW5QbG90KG1vZGVsID0gb3V0cHV0LA0KICAgICAgICAgICBjb2VmcyA9IFRSVUUsDQogICAgICAgICAgIHN0YW5kID0gVFJVRSwNCiAgICAgICAgICAgc3RhcnMgPSBjKCJyZWdyZXNzIikpICAjIEFkZCBzaWduaWZpY2FuY2Ugc3RhcnMNCmBgYA0KDQpUaGUgcGF0aCBkaWFncmFtIGdlbmVyYXRlZCBieSBSIGZvciB0aGUgU0VNIGFuYWx5c2lzIGlzIG5vdCBlYXN5IHRvIHJlYWQuIFRoZXJlZm9yZSwgd2Ugc2tldGNoZWQgYSBuZXcgcGF0aCBkaWFncmFtIHRoYXQgaW5jbHVkZXMgb25seSB0aGUgc2lnbmlmaWNhbnQgcmVncmVzc2lvbiBjb2VmZmljaWVudHMgYW5kIGZhY3RvciBsb2FkaW5ncy4NCg0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIG91dC53aWR0aD0iNzAlIn0NCmluY2x1ZGVfZ3JhcGhpY3MoIkZpdHRlZGxTRU0ucG5nIikNCmBgYA0KDQojIyBSZXN1bHRzIGFuZCBEaXNjdXNzaW9uIG9mIFNFTSBBbmx5c2lzDQoNCiMjIyBSZXN1bHRzDQoNClRoZSBoeXBvdGhlc2l6ZWQgc3RydWN0dXJhbCBlcXVhdGlvbiBtb2RlbCBkZW1vbnN0cmF0ZWQgYW4gYWNjZXB0YWJsZSBmaXQgdG8gdGhlIGRhdGE6ICRcY2hpXjIoMTY4KSA9IDY2NC43NSwgcCA8IC4wMDEkOyAkQ0ZJID0gMC45Mjc7IFRMSSA9IDAuOTEzJDsgJFJNU0VBID0gMC4wNjUgKDkwJSBDSSBbMC4wNjAsIDAuMDcwXSkkOyBhbmQgJFNSTVIgPSAwLjA3MCQgVGhlc2UgZml0IGluZGljZXMgaW5kaWNhdGUgdGhhdCB0aGUgcHJvcG9zZWQgbW9kZWwgYWRlcXVhdGVseSByZXByZXNlbnRzIHRoZSBvYnNlcnZlZCBkYXRhLCB3aXRoIHZhbHVlcyBtZWV0aW5nIG9yIGV4Y2VlZGluZyBjb252ZW50aW9uYWwgdGhyZXNob2xkcyBmb3IgYWNjZXB0YWJsZSBtb2RlbCBmaXQuDQoNClNldmVyYWwgc2lnbmlmaWNhbnQgc3RydWN0dXJhbCBwYXRocyBlbWVyZ2VkLiAqKlRlY2hub2xvZ3kqKiB1c2Ugd2FzIGEgc2lnbmlmaWNhbnQgbmVnYXRpdmUgcHJlZGljdG9yIG9mIGJvdGggZXZhbHVhdGlvbiBhbnhpZXR5ICgkXGJldGEgPSDigJMwLjEzLCBwIDwgLjAwMSQpIGFuZCBsZWFybmluZyBhbnhpZXR5ICgkXGJldGEgPSDigJMwLjIwLCBwIDwgLjAwMSQpLCBzdWdnZXN0aW5nIHRoYXQgZ3JlYXRlciB0ZWNobm9sb2dpY2FsIHByb2ZpY2llbmN5IG9yIGludGVncmF0aW9uIHdhcyBhc3NvY2lhdGVkIHdpdGggcmVkdWNlZCBhbnhpZXR5IGluIGJvdGggY29udGV4dHMuIFNpbWlsYXJseSwgc2VsZi1lZmZpY2FjeSBuZWdhdGl2ZWx5IHByZWRpY3RlZCBldmFsdWF0aW9uIGFueGlldHkgKCRcYmV0YSA9IOKAkzAuNDcsIHAgPCAuMDAxJCkgYW5kIGxlYXJuaW5nIGFueGlldHkgKCRcYmV0YSA9IOKAkzAuNDIsIHAgPCAuMDAxJCksIGluZGljYXRpbmcgdGhhdCBpbmRpdmlkdWFscyB3aXRoIGhpZ2hlciBzZWxmLWVmZmljYWN5IGV4cGVyaWVuY2VkIGxvd2VyIGxldmVscyBvZiBhbnhpZXR5Lg0KDQoqKkdlbmRlcioqIGFsc28gaGFkIGEgc2lnbmlmaWNhbnQgZWZmZWN0IG9uIGV2YWx1YXRpb24gYW54aWV0eSAoJFxiZXRhID0g4oCTMC4xMywgcCA8IC4wMDEkKSwgaW1wbHlpbmcgcG90ZW50aWFsIGdlbmRlci1iYXNlZCBkaWZmZXJlbmNlcyBpbiBldmFsdWF0aW9uLXJlbGF0ZWQgYXBwcmVoZW5zaW9uLiBBbHRob3VnaCAqKnN0dWRlbnQtY2VudGVyZWQgaW5zdHJ1Y3Rpb24qKiB3YXMgbWFyZ2luYWxseSByZWxhdGVkIHRvIGxlYXJuaW5nIGFueGlldHkgKCRcYmV0YSA9IOKAkzAuNTEsIHAgPSAuMDU5JCksICoqcmVzb3VyY2UgYXZhaWxhYmlsaXR5KiogcG9zaXRpdmVseSBwcmVkaWN0ZWQgbGVhcm5pbmcgYW54aWV0eSAoJFxiZXRhID0gMC4xMiwgcCA9IC4wMDEkKSwgaW5kaWNhdGluZyB0aGF0IGFjY2VzcyB0byBhZGRpdGlvbmFsIHJlc291cmNlcyBtYXkgbm90IHVuaWZvcm1seSBhbGxldmlhdGUgYW54aWV0eSBhbmQgY291bGQsIGluIHNvbWUgY29udGV4dHMsIGNvbnRyaWJ1dGUgdG8gKmluY3JlYXNlZCBwcmVzc3VyZSogb3IgKmNvZ25pdGl2ZSBsb2FkKi4gT3RoZXIgaHlwb3RoZXNpemVkIHBhdGhzIChlLmcuLCAqKmVuZ2FnZW1lbnQqKiwgKip0ZWFjaGVyLWNlbnRlcmVkIGFwcHJvYWNoZXMqKikgd2VyZSBub3Qgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCAoYWxsICRwID4gLjA1JCkuDQoNCkFsbCBvYnNlcnZlZCBpbmRpY2F0b3JzIGxvYWRlZCBzaWduaWZpY2FudGx5IG9udG8gdGhlaXIgcmVzcGVjdGl2ZSBsYXRlbnQgY29uc3RydWN0cyAoYWxsICRwIDwgLjAwMSQpLCB3aXRoIHN0YW5kYXJkaXplZCBmYWN0b3IgbG9hZGluZ3MgcmFuZ2luZyBmcm9tIDAuNTEgdG8gMC44OCwgc3VwcG9ydGluZyBjb25zdHJ1Y3QgdmFsaWRpdHkuIEZvciBFdmFsdWF0aW9uIEFueGlldHksIHRoZSBzdHJvbmdlc3QgaW5kaWNhdG9ycyB3ZXJlICoqTUVBMioqICgkXGxhbWJkYSA9IDAuODgzJCkgYW5kICoqTUVBNCoqICgkXGxhbWJkYSA9IDAuODU3JCkuIEZvciBMZWFybmluZyBBbnhpZXR5LCB0aGUgaGlnaGVzdCBsb2FkaW5ncyB3ZXJlIG9ic2VydmVkIGZvciAqKk1MQTkqKiAoJFxsYW1iZGEgPSAwLjcyNSQpIGFuZCAqKk1MQTMqKiAoJFxsYW1iZGEgPSAwLjcxNCQpLiBBbW9uZyB0ZWFjaGluZyBhcHByb2FjaGVzLCAqKlRlYWNoZXItQ2VudGVyZWQgSW5zdHJ1Y3Rpb24qKiB3YXMgYmVzdCByZXByZXNlbnRlZCBieSAqKkRlZHVjdGl2ZSoqICgkXGxhbWJkYSA9IDAuODg2JCkgYW5kICoqTGVjdHVyZSoqICgkXGxhbWJkYSA9IDAuODY4JCkgbWV0aG9kcywgd2hpbGUgKipTdHVkZW50LUNlbnRlcmVkIEluc3RydWN0aW9uKiogd2FzIGJlc3QgcmVmbGVjdGVkIGJ5ICoqSW5kdWN0aXZlKiogKCRcbGFtYmRhID0gMC44NjIkKSBhbmQgKipDb29wZXJhdGl2ZSoqICgkXGxhbWJkYSA9IDAuNzMzJCkgc3RyYXRlZ2llcy4NCg0KVGhlIG1vZGVsIGFjY291bnRlZCBmb3IgMzQuOSUgb2YgdGhlIHZhcmlhbmNlIGluIGV2YWx1YXRpb24gYW54aWV0eSBhbmQgMzMuNCUgb2YgdGhlIHZhcmlhbmNlIGluIGxlYXJuaW5nIGFueGlldHksIGluZGljYXRpbmcgbW9kZXJhdGUgZXhwbGFuYXRvcnkgcG93ZXIuIFRoZSBjb3ZhcmlhbmNlIGJldHdlZW4gZXZhbHVhdGlvbiBhbnhpZXR5IGFuZCBsZWFybmluZyBhbnhpZXR5IHdhcyBzaWduaWZpY2FudCBhbmQgcG9zaXRpdmUgKCRyID0gMC41MyQpLCBzdWdnZXN0aW5nIHRoYXQgd2hpbGUgZGlzdGluY3QsIHRoZXNlIHR3byBmb3JtcyBvZiBhbnhpZXR5IGFyZSBtb2RlcmF0ZWx5IGNvcnJlbGF0ZWQuDQoNCk92ZXJhbGwsIHRoZSByZXN1bHRzIGhpZ2hsaWdodCB0aGUgcGl2b3RhbCByb2xlIG9mICoqc2VsZi1lZmZpY2FjeSoqIGFuZCAqKnRlY2hub2xvZ3kgdXNlKiogaW4gbWl0aWdhdGluZyBib3RoIGV2YWx1YXRpb24gYW5kIGxlYXJuaW5nLXJlbGF0ZWQgYW54aWV0eS4gVGhlc2UgZmluZGluZ3MgYWxpZ24gd2l0aCBwcmlvciByZXNlYXJjaCBlbXBoYXNpemluZyB0aGF0IGNvbmZpZGVuY2UgaW4gb25l4oCZcyBhYmlsaXRpZXMgYW5kIGZhbWlsaWFyaXR5IHdpdGggZGlnaXRhbCB0b29scyBjYW4gZW5oYW5jZSBwZXJjZWl2ZWQgY29udHJvbCBhbmQgcmVkdWNlIGFueGlldHkgaW4gYWNhZGVtaWMgY29udGV4dHMuIFRoZSBtYXJnaW5hbCBpbmZsdWVuY2Ugb2YgKipzdHVkZW50LWNlbnRlcmVkIGFwcHJvYWNoZXMqKiBzdWdnZXN0cyBwb3RlbnRpYWwgYmVuZWZpdHMgZm9yIHJlZHVjaW5nIGxlYXJuaW5nIGFueGlldHkgdGhyb3VnaCBhY3RpdmUgYW5kIHBhcnRpY2lwYXRvcnkgbGVhcm5pbmcgZW52aXJvbm1lbnRzLCBhbHRob3VnaCB0aGUgZWZmZWN0IGRpZCBub3QgcmVhY2ggY29udmVudGlvbmFsIHNpZ25pZmljYW5jZS4gVGhlIHBvc2l0aXZlIGFzc29jaWF0aW9uIGJldHdlZW4gKipyZXNvdXJjZSBhdmFpbGFiaWxpdHkqKiBhbmQgYW54aWV0eSBtYXkgaW5kaWNhdGUgdGhhdCB3aGlsZSBhY2Nlc3MgdG8gbWF0ZXJpYWxzIHN1cHBvcnRzIGxlYXJuaW5nLCBpdCBjYW4gYWxzbyBpbnRyb2R1Y2UgaW5mb3JtYXRpb24gb3ZlcmxvYWQgb3IgcGVyZm9ybWFuY2UgZXhwZWN0YXRpb25zIHRoYXQgaGVpZ2h0ZW4gYW54aWV0eS4gVG9nZXRoZXIsIHRoZXNlIGZpbmRpbmdzIHVuZGVyc2NvcmUgdGhlIG11bHRpZmFjZXRlZCBuYXR1cmUgb2YgYWNhZGVtaWMgYW54aWV0eSBhbmQgcG9pbnQgdG8gdGhlIGltcG9ydGFuY2Ugb2YgZm9zdGVyaW5nIGVmZmljYWN5IGFuZCB0ZWNobm9sb2dpY2FsIHJlYWRpbmVzcyB0byBjcmVhdGUgc3VwcG9ydGl2ZSBsZWFybmluZyBlbnZpcm9ubWVudHMuDQoNClRoZXNlIGZpbmRpbmdzIGNvbGxlY3RpdmVseSBpbmZvcm0gdGhlIHN1YnNlcXVlbnQgZGlzY3Vzc2lvbiBvbiBob3cgKippbnN0cnVjdGlvbmFsIGRlc2lnbioqLCAqKnNlbGYtZWZmaWNhY3kqKiwgYW5kICoqdGVjaG5vbG9neSBpbnRlZ3JhdGlvbioqIGludGVyYWN0IHRvIGluZmx1ZW5jZSBsZWFybmVyc+KAmSBlbW90aW9uYWwgZXhwZXJpZW5jZXMgYW5kIGFjYWRlbWljIGVuZ2FnZW1lbnQuDQoNCiMjIyBEaXNjdXNzaW9uDQoNClRoZSBwcmVzZW50IHN0dWR5IGludmVzdGlnYXRlZCB0aGUgc3RydWN0dXJhbCByZWxhdGlvbnNoaXBzIGFtb25nIHRlY2hub2xvZ3kgdXNlLCBzZWxmLWVmZmljYWN5LCBpbnN0cnVjdGlvbmFsIGFwcHJvYWNoZXMsIGFuZCB0d28gZm9ybXMgb2YgYWNhZGVtaWMgYW54aWV0eeKAlGV2YWx1YXRpb24gYW54aWV0eSBhbmQgbGVhcm5pbmcgYW54aWV0eeKAlHdpdGhpbiBhIGNvbXByZWhlbnNpdmUgc3RydWN0dXJhbCBlcXVhdGlvbiBtb2RlbGluZyAoU0VNKSBmcmFtZXdvcmsuIFRoZSBmaW5kaW5ncyBwcm92aWRlIGltcG9ydGFudCBpbnNpZ2h0cyBpbnRvIGhvdyBpbmRpdmlkdWFsIGFuZCBpbnN0cnVjdGlvbmFsIGZhY3RvcnMgam9pbnRseSBzaGFwZSBsZWFybmVyc+KAmSBlbW90aW9uYWwgZXhwZXJpZW5jZXMgaW4gYWNhZGVtaWMgY29udGV4dHMuDQoNCkNvbnNpc3RlbnQgd2l0aCBwcmlvciByZXNlYXJjaCwgc2VsZi1lZmZpY2FjeSBlbWVyZ2VkIGFzIHRoZSBtb3N0IHJvYnVzdCBwcmVkaWN0b3Igb2YgYm90aCBldmFsdWF0aW9uIGFuZCBsZWFybmluZyBhbnhpZXR5LiBTdHVkZW50cyB3aG8gcmVwb3J0ZWQgaGlnaGVyIGNvbmZpZGVuY2UgaW4gdGhlaXIgYWNhZGVtaWMgYWJpbGl0aWVzIGV4cGVyaWVuY2VkIHNpZ25pZmljYW50bHkgbG93ZXIgbGV2ZWxzIG9mIGFueGlldHksIHVuZGVyc2NvcmluZyB0aGUgcHJvdGVjdGl2ZSBmdW5jdGlvbiBvZiBzZWxmLWJlbGllZiBpbiBjb3Bpbmcgd2l0aCBhY2FkZW1pYyBkZW1hbmRzLiBTaW1pbGFybHksIHRlY2hub2xvZ3kgdXNlIG5lZ2F0aXZlbHkgcHJlZGljdGVkIGJvdGggdHlwZXMgb2YgYW54aWV0eSwgc3VnZ2VzdGluZyB0aGF0IGZhbWlsaWFyaXR5IGFuZCBjb21mb3J0IHdpdGggdGVjaG5vbG9naWNhbCB0b29scyBtYXkgaGVscCBzdHVkZW50cyBuYXZpZ2F0ZSBsZWFybmluZyBlbnZpcm9ubWVudHMgbW9yZSBlZmZlY3RpdmVseSBhbmQgcmVkdWNlIGFwcHJlaGVuc2lvbiBhYm91dCBwZXJmb3JtYW5jZS4NCg0KQWx0aG91Z2ggc3R1ZGVudC1jZW50ZXJlZCBpbnN0cnVjdGlvbiB3YXMgb25seSBtYXJnaW5hbGx5IGFzc29jaWF0ZWQgd2l0aCByZWR1Y2VkIGxlYXJuaW5nIGFueGlldHksIHRoZSBkaXJlY3Rpb24gb2YgdGhpcyByZWxhdGlvbnNoaXAgaXMgdGhlb3JldGljYWxseSBtZWFuaW5nZnVsLiBMZWFybmVycyBleHBvc2VkIHRvIGluZHVjdGl2ZSwgY29vcGVyYXRpdmUsIGFuZCBpbnRlZ3JhdGl2ZSB0ZWFjaGluZyBzdHJhdGVnaWVzIG1heSBwZXJjZWl2ZSBncmVhdGVyIGF1dG9ub215IGFuZCBzdXBwb3J0LCB3aGljaCBjYW4gbGVzc2VuIGFueGlldHkgYW5kIGZvc3RlciBpbnRyaW5zaWMgbW90aXZhdGlvbi4gVGhlIHBvc2l0aXZlIGFzc29jaWF0aW9uIGJldHdlZW4gcmVzb3VyY2UgYXZhaWxhYmlsaXR5IGFuZCBsZWFybmluZyBhbnhpZXR5IHN1Z2dlc3RzIHRoYXQgYWNjZXNzIHRvIGFidW5kYW50IG1hdGVyaWFscyBkb2VzIG5vdCBuZWNlc3NhcmlseSBhbGxldmlhdGUgc3RyZXNzOyBpbnN0ZWFkLCBpdCBtYXkgaW50cm9kdWNlIGNvZ25pdGl2ZSBvdmVybG9hZCBvciBwZXJmb3JtYW5jZSBwcmVzc3VyZS4NCg0KR2VuZGVyIHNpZ25pZmljYW50bHkgcHJlZGljdGVkIGV2YWx1YXRpb24gYW54aWV0eSwgaGlnaGxpZ2h0aW5nIHRoZSBpbXBvcnRhbmNlIG9mIGNvbnNpZGVyaW5nIHNvY2lvY3VsdHVyYWwgYW5kIGRpc2NpcGxpbmFyeSBmYWN0b3JzIHRoYXQgc2hhcGUgaG93IGdlbmRlciBpbnRlcmFjdHMgd2l0aCBhY2FkZW1pYyBlbW90aW9ucy4gVGhlIHN0cm9uZyBwb3NpdGl2ZSBjb3ZhcmlhbmNlIGJldHdlZW4gZXZhbHVhdGlvbiBhbmQgbGVhcm5pbmcgYW54aWV0eSBpbmRpY2F0ZXMgdGhhdCB0aGVzZSBjb25zdHJ1Y3RzIGFyZSByZWxhdGVkIHlldCBkaXN0aW5jdCwgc3VwcG9ydGluZyB0aGVvcmllcyB0aGF0IGVtcGhhc2l6ZSBpbnRlcmNvbm5lY3RlZCBlbW90aW9uYWwgZXhwZXJpZW5jZXMgaW4gbGVhcm5pbmcuDQoNClRoZSBmaW5kaW5ncyB1bmRlcnNjb3JlIHRoZSBuZWVkIGZvciBpbnN0cnVjdGlvbmFsIGRlc2lnbnMgdGhhdCBlbmhhbmNlIHNlbGYtZWZmaWNhY3kgYW5kIHRlY2hub2xvZ2ljYWwgY29uZmlkZW5jZSBhcyBjZW50cmFsIHN0cmF0ZWdpZXMgZm9yIHJlZHVjaW5nIGFjYWRlbWljIGFueGlldHkuIEluc3RydWN0b3JzIGNhbiBwcm9tb3RlIHNlbGYtZWZmaWNhY3kgdGhyb3VnaCBzY2FmZm9sZGVkIGZlZWRiYWNrLCBtYXN0ZXJ5LW9yaWVudGVkIGFzc2Vzc21lbnRzLCBhbmQgb3Bwb3J0dW5pdGllcyBmb3Igc2VsZi1yZWZsZWN0aW9uLiBQdXJwb3NlZnVsIHRlY2hub2xvZ3kgaW50ZWdyYXRpb24gYW5kIHN0cnVjdHVyZWQgZ3VpZGFuY2UgY2FuIGZ1cnRoZXIgc3VwcG9ydCBjb25maWRlbmNlIGFuZCByZWR1Y2UgYW54aWV0eS4gRnV0dXJlIHN0dWRpZXMgc2hvdWxkIGV4cGxvcmUgYWRkaXRpb25hbCBwcmVkaWN0b3JzIGFuZCBjb250ZXh0dWFsIHZhcmlhYmxlcywgYXMgd2VsbCBhcyBlbXBsb3kgbG9uZ2l0dWRpbmFsIGRlc2lnbnMgdG8gY2xhcmlmeSBjYXVzYWwgcGF0aHdheXMuDQoNCkluIHN1bW1hcnksIHRoZSBmaW5kaW5ncyBkZW1vbnN0cmF0ZSB0aGF0IHNlbGYtZWZmaWNhY3kgYW5kIHRlY2hub2xvZ3kgdXNlIGFyZSBrZXkgcHJvdGVjdGl2ZSBmYWN0b3JzIGFnYWluc3QgYm90aCBldmFsdWF0aW9uIGFuZCBsZWFybmluZyBhbnhpZXR5LCB3aGVyZWFzIGluc3RydWN0aW9uYWwgY29udGV4dCBhbmQgcmVzb3VyY2UgbWFuYWdlbWVudCBwbGF5IHNlY29uZGFyeSByb2xlcy4gVGhlc2UgaW5zaWdodHMgY29udHJpYnV0ZSB0byBhIGdyb3dpbmcgdW5kZXJzdGFuZGluZyBvZiBob3cgcGVyc29uYWwgYW5kIHBlZGFnb2dpY2FsIGZhY3RvcnMgaW50ZXJhY3QgdG8gc2hhcGUgZW1vdGlvbmFsIGV4cGVyaWVuY2VzIGluIGxlYXJuaW5nIGVudmlyb25tZW50cy4NCg0KIyMjIFByYWN0aWNhbCBJbXBsaWNhdGlvbnMNCg0KMS4gRW5oYW5jZSBTdHVkZW50c+KAmSBTZWxmLUVmZmljYWN5OiBQcm92aWRlIG9wcG9ydHVuaXRpZXMgZm9yIGVhcmx5IHN1Y2Nlc3MsIG1hc3RlcnkgZXhwZXJpZW5jZXMsIGFuZCBwb3NpdGl2ZSBmZWVkYmFjayB0byBidWlsZCBsZWFybmVyc+KAmSBjb25maWRlbmNlLg0KMi4gUHJvbW90ZSBNZWFuaW5nZnVsIFRlY2hub2xvZ3kgSW50ZWdyYXRpb246IEludGVncmF0ZSBkaWdpdGFsIHRvb2xzIHB1cnBvc2VmdWxseSB3aXRoaW4gaW5zdHJ1Y3Rpb24gdG8gZm9zdGVyIGVuZ2FnZW1lbnQgYW5kIHJlZHVjZSB0ZWNobm9sb2d5LXJlbGF0ZWQgYW54aWV0eS4NCjMuIEFkb3B0IFN0dWRlbnQtQ2VudGVyZWQgVGVhY2hpbmcgUHJhY3RpY2VzOiBFbmNvdXJhZ2UgY29sbGFib3JhdGl2ZSwgcHJvYmxlbS1iYXNlZCwgYW5kIHBlZXItZHJpdmVuIGxlYXJuaW5nIHRvIGFsbGV2aWF0ZSBhbnhpZXR5IGFuZCBwcm9tb3RlIGF1dG9ub215Lg0KNC4gQmFsYW5jZSBSZXNvdXJjZSBQcm92aXNpb24gYW5kIENvZ25pdGl2ZSBMb2FkOiBDdXJhdGUgaW5zdHJ1Y3Rpb25hbCBtYXRlcmlhbHMgY2FyZWZ1bGx5IHRvIHByZXZlbnQgaW5mb3JtYXRpb24gb3ZlcmxvYWQgYW5kIGVuc3VyZSBjbGFyaXR5IG9mIGV4cGVjdGF0aW9ucy4NCjUuIEFkZHJlc3MgR2VuZGVyIGFuZCBDb250ZXh0dWFsIERpZmZlcmVuY2VzOiBUYWlsb3Igc3VwcG9ydCBzdHJhdGVnaWVzIHRvIGFkZHJlc3MgcG90ZW50aWFsIGdlbmRlci1iYXNlZCBhbmQgY29udGV4dHVhbCB2YXJpYXRpb25zIGluIGFjYWRlbWljIGFueGlldHkuDQoNCiMjIyBTdW1tYXJ5IG9mIEtleSBGaW5kaW5ncw0KDQpUaGlzIHN0dWR5IGVtcGxveWVkIHN0cnVjdHVyYWwgZXF1YXRpb24gbW9kZWxpbmcgdG8gZXhhbWluZSB0aGUgaW50ZXJwbGF5IGFtb25nIHRlY2hub2xvZ3kgdXNlLCBzZWxmLWVmZmljYWN5LCBpbnN0cnVjdGlvbmFsIGFwcHJvYWNoZXMsIGFuZCB0d28gZGltZW5zaW9ucyBvZiBhY2FkZW1pYyBhbnhpZXR5OiBldmFsdWF0aW9uIGFueGlldHkgYW5kIGxlYXJuaW5nIGFueGlldHkuIFRoZSBtb2RlbCBkZW1vbnN0cmF0ZWQgYW4gYWNjZXB0YWJsZSBvdmVyYWxsIGZpdCBhbmQgZXhwbGFpbmVkIGEgc3Vic3RhbnRpYWwgcHJvcG9ydGlvbiBvZiB2YXJpYW5jZSBpbiBib3RoIG91dGNvbWVzLg0KDQpUaGUgcmVzdWx0cyByZXZlYWxlZCB0aGF0IHNlbGYtZWZmaWNhY3kgYW5kIHRlY2hub2xvZ3kgdXNlIHdlcmUgdGhlIHN0cm9uZ2VzdCBwcm90ZWN0aXZlIGZhY3RvcnMgYWdhaW5zdCBhY2FkZW1pYyBhbnhpZXR5LiBTZWxmLWVmZmljYWN5IGhhZCB0aGUgbGFyZ2VzdCBuZWdhdGl2ZSBhc3NvY2lhdGlvbnMgd2l0aCBib3RoIGV2YWx1YXRpb24gYW5kIGxlYXJuaW5nIGFueGlldHksIGluZGljYXRpbmcgdGhhdCBzdHVkZW50cyB3aG8gZmVlbCBjb21wZXRlbnQgYXJlIGxlc3MgbGlrZWx5IHRvIGV4cGVyaWVuY2UgYW54aWV0eSBhY3Jvc3MgYWNhZGVtaWMgY29udGV4dHMuIFRlY2hub2xvZ3kgdXNlIHNpbWlsYXJseSByZWR1Y2VkIGFueGlldHksIHN1Z2dlc3RpbmcgdGhhdCBmYW1pbGlhcml0eSB3aXRoIGRpZ2l0YWwgdG9vbHMgZm9zdGVycyBjb21mb3J0IGFuZCBwZXJjZWl2ZWQgY29udHJvbCBkdXJpbmcgbGVhcm5pbmcgYW5kIGFzc2Vzc21lbnQuDQoNCldoaWxlIHN0dWRlbnQtY2VudGVyZWQgaW5zdHJ1Y3Rpb24gc2hvd2VkIGEgbWFyZ2luYWxseSBuZWdhdGl2ZSByZWxhdGlvbnNoaXAgd2l0aCBsZWFybmluZyBhbnhpZXR5LCByZXNvdXJjZSBhdmFpbGFiaWxpdHkgdW5leHBlY3RlZGx5IHByZWRpY3RlZCBoaWdoZXIgYW54aWV0eS4gR2VuZGVyIGRpZmZlcmVuY2VzIGFsc28gZW1lcmdlZCBmb3IgZXZhbHVhdGlvbiBhbnhpZXR5LCBzdWdnZXN0aW5nIHZhcmlhdGlvbiBpbiBlbW90aW9uYWwgcmVzcG9uc2VzIHRvIGFjYWRlbWljIGV2YWx1YXRpb24gYWNyb3NzIGdyb3Vwcy4NCg0KVG9nZXRoZXIsIHRoZXNlIGZpbmRpbmdzIGRlbW9uc3RyYXRlIHRoYXQgZm9zdGVyaW5nIHNlbGYtZWZmaWNhY3ksIGRpZ2l0YWwgY29tcGV0ZW5jZSwgYW5kIGJhbGFuY2VkIGluc3RydWN0aW9uYWwgZGVzaWduIGNhbiBzdWJzdGFudGlhbGx5IHJlZHVjZSBzdHVkZW50c+KAmSBhbnhpZXR5IGFuZCBwcm9tb3RlIG1vcmUgcG9zaXRpdmUgYWNhZGVtaWMgZXhwZXJpZW5jZXMuIFRoZSBzdHVkeSBjb250cmlidXRlcyB0byBhIGdyb3dpbmcgYm9keSBvZiBldmlkZW5jZSBoaWdobGlnaHRpbmcgdGhlIGludGVyY29ubmVjdGVkIHJvbGVzIG9mIHBlcnNvbmFsIGJlbGllZnMsIHRlY2hub2xvZ3ksIGFuZCBwZWRhZ29neSBpbiBzaGFwaW5nIHN0dWRlbnRz4oCZIGVtb3Rpb25hbCBlbmdhZ2VtZW50IGFuZCBzdWNjZXNzLg0KDQpcDQoNCiMgUmVmZXJlbmNlcw0KDQpCb3JpY2gsIEcuIEQuICgyMDE3KS4gRWZmZWN0aXZlIFRlYWNoaW5nIE1ldGhvZHM6IFJlc2VhcmNoLUJhc2VkIFByYWN0aWNlICg5dGggZWQuKS4gUGVhcnNvbi4gDQpCcm93biwgSC4gRC4sICYgTGVlLCBILiAoMTk5NCkuIFRlYWNoaW5nIGJ5IHByaW5jaXBsZXM6IEFuIGludGVyYWN0aXZlIGFwcHJvYWNoIHRvIGxhbmd1YWdlIHBlZGFnb2d5IChWb2wuIDEsIHAuIDk5NCkuIEVuZ2xld29vZCBDbGlmZnMsIE5KOiBQcmVudGljZSBIYWxsIFJlZ2VudHMuDQoNCkJydW5lciwgSi4gUy4gKDE5NjEpLiBUaGUgYWN0IG9mIGRpc2NvdmVyeS4gSGFydmFyZCBlZHVjYXRpb25hbCByZXZpZXcuDQpDYXR0ZWxsLCBSLiBCLiAoMTk1MikuIEZhY3RvciBhbmFseXNpczogYW4gaW50cm9kdWN0aW9uIGFuZCBtYW51YWwgZm9yIHRoZSBwc3ljaG9sb2dpc3QgYW5kIHNvY2lhbCBzY2llbnRpc3QuDQoNCkNoYW5nLCBILiwgJiBCZWlsb2NrLCBTLiBMLiAoMjAxNikuIFRoZSBtYXRoIGFueGlldHktbWF0aCBwZXJmb3JtYW5jZSBsaW5rIGFuZCBpdHMgcmVsYXRpb24gdG8gaW5kaXZpZHVhbCBhbmQgZW52aXJvbm1lbnRhbCBmYWN0b3JzOiBBIHJldmlldyBvZiBjdXJyZW50IGJlaGF2aW9yYWwgYW5kIHBzeWNob3BoeXNpb2xvZ2ljYWwgcmVzZWFyY2guIEN1cnJlbnQgT3BpbmlvbiBpbiBCZWhhdmlvcmFsIFNjaWVuY2VzLCAxMCwgMzPigJMzOC4NCg0KQ3JvbmJhY2gsIEwuIEouICgxOTUxKS4gQ29lZmZpY2llbnQgYWxwaGEgYW5kIHRoZSBpbnRlcm5hbCBzdHJ1Y3R1cmUgb2YgdGVzdHMuIEJpb21ldHJpa2EsIDE2LCAyOTfigJMzMzUuDQoNCkRha2VyLCBSLiBKLiwgR2F0dGFzLCBTLiBVLiwgU29rb2xvd3NraSwgSC4gTS4sIEdyZWVuLCBBLiBFLiwgJiBMeW9ucywgSS4gTS4gKDIwMjEpLiBGaXJzdC15ZWFyIHN0dWRlbnRz4oCZIG1hdGggYW54aWV0eSBwcmVkaWN0cyBTVEVNIGF2b2lkYW5jZSBhbmQgdW5kZXJwZXJmb3JtYW5jZSB0aHJvdWdob3V0IHVuaXZlcnNpdHksIGluZGVwZW5kZW50bHkgb2YgbWF0aCBhYmlsaXR5LiBOcGogU2NpZW5jZSBvZiBMZWFybmluZywgNigxKSwgMTcuDQoNCkRldmluZSwgQS4sIEZhd2NldHQsIEsuLCBTesWxY3MsIEQuLCAmIERvd2tlciwgQS4gKDIwMTIpLiBHZW5kZXIgZGlmZmVyZW5jZXMgaW4gbWF0aGVtYXRpY3MgYW54aWV0eSBhbmQgdGhlIHJlbGF0aW9uIHRvIG1hdGhlbWF0aWNzIHBlcmZvcm1hbmNlIHdoaWxlIGNvbnRyb2xsaW5nIGZvciB0ZXN0IGFueGlldHkuIEJlaGF2aW9yYWwgYW5kIGJyYWluIGZ1bmN0aW9ucywgOCgxKSwgMzMuDQoNCkRpU3RlZmFubywgQy4sIFpodSwgTS4sICYgTWluZHJpbGEsIEQuICgyMDA5KS4gVW5kZXJzdGFuZGluZyBhbmQgdXNpbmcgZmFjdG9yIHNjb3JlczogQ29uc2lkZXJhdGlvbnMgZm9yIHRoZSBhcHBsaWVkIHJlc2VhcmNoZXIuIFByYWN0aWNhbCBhc3Nlc3NtZW50LCByZXNlYXJjaCwgYW5kIGV2YWx1YXRpb24sIDE0KDEpLg0KDQpEcmVnZXIsIFIuIE0uLCAmIEFpa2VuIEpyLCBMLiBSLiAoMTk1NykuIFRoZSBpZGVudGlmaWNhdGlvbiBvZiBudW1iZXIgYW54aWV0eSBpbiBhIGNvbGxlZ2UgcG9wdWxhdGlvbi4gSm91cm5hbCBvZiBFZHVjYXRpb25hbCBQc3ljaG9sb2d5LCA0OCg2KSwgMzQ0Lg0KDQpEdW5jYW4sIE8uIEQuICgxOTYxKS4gQSBzb2Npb2Vjb25vbWljIGluZGV4IGZvciBhbGwgb2NjdXBhdGlvbnMuIE9jY3VwYXRpb25zIGFuZCBzb2NpYWwgc3RhdHVzLi4NCg0KRWxzZS1RdWVzdCwgTi4gTS4sIEh5ZGUsIEouIFMuLCAmIExpbm4sIE0uIEMuICgyMDEwKS4gQ3Jvc3MtbmF0aW9uYWwgcGF0dGVybnMgb2YgZ2VuZGVyIGRpZmZlcmVuY2VzIGluIG1hdGhlbWF0aWNzOiBhIG1ldGEtYW5hbHlzaXMuIFBzeWNob2xvZ2ljYWwgYnVsbGV0aW4sIDEzNigxKSwgMTAzLg0KDQpGb2dhcnR5LCBSLiAoMTk5MSkuIFRoZSBtaW5kZnVsIHNjaG9vbDogSG93IHRvIGludGVncmF0ZSB0aGUgY3VycmljdWxhLiBQYWxhdGluZSwgSUwuIFNreUxpZ2h0IFB1Ymxpc2hpbmcsIEluYy4gUmV0cmlldmVkIEZlYnJ1YXJ5LCAyMiwgMjAwMi4NCg0KR29ldHosIFQuLCBCaWVnLCBNLiwgTMO8ZHRrZSwgTy4sIFBla3J1biwgUi4sICYgSGFsbCwgTi4gQy4gKDIwMTMpLiBEbyBnaXJscyByZWFsbHkgZXhwZXJpZW5jZSBtb3JlIGFueGlldHkgaW4gbWF0aGVtYXRpY3M/LiBQc3ljaG9sb2dpY2FsIHNjaWVuY2UsIDI0KDEwKSwgMjA3OS0yMDg3Lg0KDQpHb3VnaCwgTWFyeSBPLiAoMTk1NCkuIFdoeSBmYWlsdXJlcyBpbiBtYXRoZW1hdGljcz8gTWF0aGVtYXBob2JpYTogQ2F1c2VzIGFuZCB0cmVhdG1lbnRzLiBUaGUgQ2xlYXJpbmcgSG91c2U6IEEgSm91cm5hbCBvZiBFZHVjYXRpb25hbCBTdHJhdGVnaWVzLCBJc3N1ZXMgYW5kIElkZWFzLCAyOCg1KSwgMjkw4oCTMjk0LiANCg0KR3V0dG1hbiwgTC4gKDE5NTQpLiBTb21lIG5lY2Vzc2FyeSBjb25kaXRpb25zIGZvciBjb21tb24tZmFjdG9yIGFuYWx5c2lzLiBQc3ljaG9tZXRyaWthLCAxOSgyKSwgMTQ5LTE2MS4NCg0KSGVtYnJlZSwgUi4gKDE5OTApLiBUaGUgbmF0dXJlLCBlZmZlY3RzLCBhbmQgcmVsaWVmIG9mIG1hdGhlbWF0aWNzIGFueGlldHkuIEpvdXJuYWwgZm9yIHJlc2VhcmNoIGluIG1hdGhlbWF0aWNzIGVkdWNhdGlvbiwgMjEoMSksIDMzLTQ2Lg0KDQpIb3BrbywgRC4gUi4sIE1haGFkZXZhbiwgUi4sIEJhcmUsIFIuIEwuLCAmIEh1bnQsIE0uIEsuICgyMDAzKS4gVGhlIGFiYnJldmlhdGVkIG1hdGggYW54aWV0eSBzY2FsZSAoQU1BUykgY29uc3RydWN0aW9uLCB2YWxpZGl0eSwgYW5kIHJlbGlhYmlsaXR5LiBBc3Nlc3NtZW50LCAxMCgyKSwgMTc44oCTMTgyLg0KDQogSGlyc2NoYmVyZywgRS4sICYgU3RhbmRpc2gsIEMuIFYuICgxOTU5KS4gQSBtZXRob2Qgb2YgZGVyaXZpbmcgYSBzdHJhdGlmaWNhdGlvbiBzY29yZSBieSB1c2luZyB0aGUgcHJpbmNpcGFsIGNvbXBvbmVudHMgb2YgdGhlIGNvcnJlbGF0aW9uIG1hdHJpeC4gQW1lcmljYW4gU3RhdGlzdGljYWwgQXNzb2NpYXRpb24sIFByb2NlZWRpbmdzIG9mIHRoZSBTb2NpYWwgU3RhdGlzdGljcyBTZWN0aW9uLCAxOTU5LCAyMjAtMjI1Lg0KDQpKYWNvYnMsIEguIEguICgxOTg5KS4gSW50ZXJkaXNjaXBsaW5hcnkgY3VycmljdWx1bTogRGVzaWduIGFuZCBpbXBsZW1lbnRhdGlvbi4gQXNzb2NpYXRpb24gZm9yIFN1cGVydmlzaW9uIGFuZCBDdXJyaWN1bHVtIERldmVsb3BtZW50LCAxMjUwIE4uIFBpdHQgU3RyZWV0LCBBbGV4YW5kcmlhLCBWQSAyMjMxNC4NCg0KSm9sbGlmZmUsIEkuIFQuLCAmIENhZGltYSwgSi4gKDIwMTYpLiBQcmluY2lwYWwgQ29tcG9uZW50IEFuYWx5c2lzOiBBIFJldmlldyBhbmQgUmVjZW50IERldmVsb3BtZW50cy4gUGhpbG9zb3BoaWNhbCBUcmFuc2FjdGlvbnMgb2YgdGhlIFJveWFsIFNvY2lldHkgQSwgMzc0KDIwNjUpLCAyMDE1MDIwMi4NCg0KSm9obnNvbiwgRC4gVy4sIEpvaG5zb24sIFIuIFQuLCAmIFNtaXRoLCBLLiBBLiAoMjAxNCkuIENvb3BlcmF0aXZlIGxlYXJuaW5nOiBJbXByb3ZpbmcgdW5pdmVyc2l0eSBpbnN0cnVjdGlvbiBieSBiYXNpbmcgcHJhY3RpY2Ugb24gdmFsaWRhdGVkIHRoZW9yeS4gSm91cm5hbCBvbiBleGNlbGxlbmNlIGluIGNvbGxlZ2UgdGVhY2hpbmcsIDI1KDMmNCkuDQoNCkpvc2UgTS4gQ2FyZGlubyBKci4gYW5kIFJ1dGggQS4gT3J0ZWdhLURlbGEgQ3J1eiwgVW5kZXJzdGFuZGluZyBvZiBsZWFybmluZyBzdHlsZXMgYW5kIHRlYWNoaW5nIHN0cmF0ZWdpZXMgdG93YXJkcyBpbXByb3ZpbmcgdGhlIHRlYWNoaW5nIGFuZCBsZWFybmluZyBvZiBtYXRoZW1hdGljcywgTFVNQVQgR2VuZXJhbCBJc3N1ZSwgIFZvbCA4IE5vIDEgKDIwMjApLCAxOeKAkzQzLiBEb2k6IDEwLjMxMTI5LyBMVU1BVC44LjEuMTM0OA0KDQpKb3ljZSwgQi4sIFdlaWwsIE0uLCAmIENhbGhvdW4sIEUuICgyMDE1KS4gTW9kZWxzIG9mIFRlYWNoaW5nICg5dGggZWQuKS4gUGVhcnNvbi4NCg0KS2xlZSwgSC4gTC4sIEJ1ZWhsLCBNLiBNLiwgJiBNaWxsZXIsIEEuIEQuICgyMDIyKS4gU3RyYXRlZ2llcyBmb3IgYWxsZXZpYXRpbmcgc3R1ZGVudHPigJkgbWF0aCBhbnhpZXR5OiBDb250cm9sLXZhbHVlIHRoZW9yeSBpbiBwcmFjdGljZS4gVGhlb3J5IEludG8gUHJhY3RpY2UsIDYxKDEpLCA0OeKAkzYxLg0KDQpMYXphcnNmZWxkLCBQLiBGLiwgU3RvdWZmZXIsIFMuIEEuLCBHdXR0bWFuLCBMLiwgJiBTdWNobWFuLCBFLiBBLiAoMTk1MCkuIE1lYXN1cmVtZW50IGFuZCBwcmVkaWN0aW9uLiBTQSBTdG91ZmZlciAow6lkLikgU3R1ZGllcyBpbiBzb2NpYWwgcHN5Y2hvbG9neSBpbiB3b3JsZCB3YXIgSUksIDQuDQoNCkzDs3Blei1Cb25pbGxhLCBKLiBNLmwgYW5kIEzDs3Blei1Cb25pbGxhLCBMLiBNLiAoMjAxMiksIFZhbGlkYXRpb24gb2YgYW4gaW5mb3JtYXRpb24gdGVjaG5vbG9neSBhbnhpZXR5IHNjYWxlIGluIHVuZGVyZ3JhZHVhdGVzLCBCcml0aXNoIEpvdXJuYWwgb2YgRWR1Y2F0aW9uYWwgVGVjaG5vbG9neSBWb2wgNDMuIE5vIDIuICBFNTbigJNFNTguICBkb2k6MTAuMTExMS9qLjE0NjctODUzNS4yMDExLjAxMjU2LngNCg0KTWFyc2gsIEguIFcuICgxOTk2KS4gUG9zaXRpdmUgYW5kIG5lZ2F0aXZlIHNlbGYtZXN0ZWVtOiBBIHN1YnN0YW50aXZlbHkgbWVhbmluZ2Z1bCBkaXN0aW5jdGlvbiBvciBhcnRpZmFjdG9ycz8gSm91cm5hbCBvZiBQZXJzb25hbGl0eSBhbmQgU29jaWFsIFBzeWNob2xvZ3ksIDcwKDQpLCA4MTDigJM4MTkuDQoNCk1jRG9uYWxkLCBSLiBQLiAoMTk5OSkuIFRlc3QgdGhlb3J5OiBBIHVuaWZpZWQgdHJlYXRtZW50LiBNYWh3YWg6IEVybGJhdW0uDQoNCk1vbGluZXIsIEwuLCAmIEFsZWdyZSwgRi4gKDIwMjApLiBQZWVyIHR1dG9yaW5nIGVmZmVjdHMgb24gc3R1ZGVudHPigJkgbWF0aGVtYXRpY3MgYW54aWV0eTogQSBtaWRkbGUgc2Nob29sIGV4cGVyaWVuY2UuIEZyb250aWVycyBpbiBQc3ljaG9sb2d5LCAxMSwgMTYxMC4NCg0KT+KAmUxlYXJ5LCBLLiwgRml0enBhdHJpY2ssIEMuIEwuLCAmIEhhbGxldHQsIEQuICgyMDE3KS4gTWF0aCBhbnhpZXR5IGlzIHJlbGF0ZWQgdG8gc29tZSwgYnV0IG5vdCBhbGwsIGV4cGVyaWVuY2VzIHdpdGggbWF0aC4gRnJvbnRpZXJzIGluIFBzeWNob2xvZ3ksIDgsIDIwNjcuDQoNCk9ybXJvZCwgSi4gRS4gKDIwMjApLiBIdW1hbiBMZWFybmluZyAoOHRoIGVkLikuIFBlYXJzb24NCg0KUGxldHplciwgQi4sIFdvb2QsIEcuLCBTY2hlcm5kbCwgVC4sIEtlcnNjaGJhdW0sIEguIEguLCAmIE51ZXJrLCBILkMuICgyMDE2KS4gQ29tcG9uZW50cyBvZiBtYXRoZW1hdGljcyBhbnhpZXR5OiBGYWN0b3IgbW9kZWxpbmcgb2YgdGhlIE1BUlMzMC1icmllZi4gRnJvbnRpZXJzIGluIFBzeWNob2xvZ3ksIDcsIDkxLg0KDQpQcmluY2UsIE0uIEouLCAmIEZlbGRlciwgUi4gTS4gKDIwMDYpLiBJbmR1Y3RpdmUgdGVhY2hpbmcgYW5kIGxlYXJuaW5nIG1ldGhvZHM6IERlZmluaXRpb25zLCBjb21wYXJpc29ucywgYW5kIHJlc2VhcmNoIGJhc2VzLiBKb3VybmFsIG9mIGVuZ2luZWVyaW5nIGVkdWNhdGlvbiwgOTUoMiksIDEyMy0xMzguDQoNClJpY2hhcmRzb24sIEYuIEMuLCAmIFN1aW5uLCBSLiBNLiAoMTk3MikuIFRoZSBtYXRoZW1hdGljcyBhbnhpZXR5IHJhdGluZyBzY2FsZTogUHN5Y2hvbWV0cmljIGRhdGEuIEpvdXJuYWwgb2YgQ291bnNlbGluZyBQc3ljaG9sb2d5LCAxOSg2KSwgNTUxLg0KDQpSb3pnb25qdWssIEQuLCBLcmFhdiwgVC4sIE1pa2tvciwgSy4sIE9yYXYtUHV1cmFuZCwgSy4sICYgVMOkaHQsIEsuICgyMDIwKS4gTWF0aGVtYXRpY3MgYW54aWV0eSBhbW9uZyBTVEVNIGFuZCBzb2NpYWwgc2NpZW5jZSBzdHVkZW50czogVGhlIHJvbGVzIG9mIG1hdGhlbWF0aWNzIHNlbGYtZWZmaWNhY3ksIGFuZCBkZWVwIGFuZCBzdXJmYWNlIGFwcHJvYWNoIHRvIGxlYXJuaW5nLiBJbnRlcm5hdGlvbmFsIEpvdXJuYWwgb2YgU1RFTSBFZHVjYXRpb24sIDcoMSksIDHigJMxMS4NCg0KU2Vnb29sLCBOLiBLLiwgQ2FybHNvbiwgSi4gUy4sIEdvZm9ydGgsIEEuIE4uLCBWb24gRGVyIEVtYnNlLCBOLiwgJiBCYXJ0ZXJpYW4sIEouIEEuICgyMDEzKS4gSGVpZ2h0ZW5lZCB0ZXN0IGFueGlldHkgYW1vbmcgeW91bmcgY2hpbGRyZW46IEVsZW1lbnRhcnkgc2Nob29sIHN0dWRlbnRz4oCZIGFueGlvdXMgcmVzcG9uc2VzIHRvIGhpZ2gtc3Rha2VzIHRlc3RpbmcuIFBzeWNob2xvZ3kgaW4gdGhlIFNjaG9vbHMsIDUwKDUpLCA0ODnigJM0OTkuDQoNCldhdHNvbiwgRC4sIENsYXJrLCBMLiBBLiwgJiBUZWxsZWdlbiwgQS4gKDE5ODgpLiBEZXZlbG9wbWVudCBhbmQgdmFsaWRhdGlvbiBvZiBicmllZiBtZWFzdXJlcyBvZiBwb3NpdGl2ZSBhbmQgbmVnYXRpdmUgYWZmZWN0OiBUaGUgUEFOQVMgc2NhbGVzLiBKb3VybmFsIG9mIFBlcnNvbmFsaXR5IGFuZCBTb2NpYWwgUHN5Y2hvbG9neSwgNTQoNiksIDEwNjPigJMxMDcwLg0KDQpXaWxzb24sIFMuICgyMDEzKS4gTWF0dXJlIGFnZSBwcmUtc2VydmljZSB0ZWFjaGVyc+KAmSBtYXRoZW1hdGljcyBhbnhpZXR5IGFuZCBmYWN0b3JzIGltcGFjdGluZyBvbiB1bml2ZXJzaXR5IHJldGVudGlvbi4gTWF0aGVtYXRpY3MgRWR1Y2F0aW9uOiBZZXN0ZXJkYXksIFRvZGF5IGFuZCBUb21vcnJvdyAoTUVSR0EzNiksIDY2NuKAkzY3My4NCg0KDQoNClwNCg0KIyBBcHBlbmRpY2VzDQoNCiMjIE1hdGhlbWF0aWNzIG9mIFBDQQ0KDQoNCioqMS4gUHJvYmxlbSBEZWZpbml0aW9uKioNCg0KV2Ugd2lsbCB1c2UgYSBxdWVzdGlvbm5haXJlIHdpdGggZm91ciBpdGVtcyB0aGF0IGFzc2VzcyBtYXRoIGV2YWx1YXRpb24gYW54aWV0eSB0byBkZW1vbnN0cmF0ZSB0aGUgcHJvY2VkdXJlLg0KDQoqICR4XzEkOiBUaGlua2luZyBhYm91dCBhIG1hdGggdGVzdCB0aGUgZGF5IGJlZm9yZSB5b3UgdGFrZSBpdC4NCiogJHhfMiQ6IFRha2luZyBhIG1hdGggdGVzdC4NCiogJHhfMyQ6IEJlaW5nIGdpdmVuIGEgaG9tZXdvcmsgYXNzaWdubWVudCBvZiBtYW55IGRpZmZpY3VsdCBwcm9ibGVtcyB0aGF0IGlzIGR1ZSBmb3IgdGhlIG5leHQgY2xhc3MgbWVldGluZy4NCiogJHhfNCQ6IEJlaW5nIGdpdmVuIGEgcXVpeiBvbiBtYXRoIHdpdGhvdXQga25vd2luZyBpbiBhZHZhbmNlLg0KDQoNCkxldCAkXG1hdGhiZnt4fSA9IFt4XzEsIHhfMiwgeF8zLCB4XzRdXlQkIGJlIGEgcmFuZG9tIHZlY3RvciByZXByZXNlbnRpbmcgdGhlIHJlc3BvbnNlcyBvZiBhIHJhbmRvbWx5IHNlbGVjdGVkIGluZGl2aWR1YWwgdG8gdGhlIGZvdXIgaXRlbXMuIFdlIGFzc3VtZSAkXG1hdGhiZnt4fSQgaGFzIGEgcG9wdWxhdGlvbiBtZWFuIHZlY3RvciAkXGJvbGRzeW1ib2x7XG11fSQgYW5kIHBvcHVsYXRpb24gY292YXJpYW5jZSBtYXRyaXggJFxib2xkc3ltYm9se1xTaWdtYX0kLg0KDQpXZSBjb2xsZWN0IGEgc2FtcGxlIG9mICRuJCBpbmRpdmlkdWFscy4gVGhlIGRhdGEgbWF0cml4IGlzICRcbWF0aGJme1h9X3tuIFx0aW1lcyA0fSQsIHdoZXJlIGVhY2ggcm93IGlzIGFuIGluZGl2aWR1YWwncyByZXNwb25zZSB2ZWN0b3IuIFRoZSBzYW1wbGUgbWVhbiB2ZWN0b3IgaXMgJFxiYXJ7XG1hdGhiZnt4fX0kLCBhbmQgdGhlIHNhbXBsZSBjb3ZhcmlhbmNlIG1hdHJpeCBpcyAkXG1hdGhiZntTfSQuDQoNCioqMi4gUHJlcHJvY2Vzc2luZzogQ2VudGVyaW5nIHRoZSBEYXRhKioNCg0KVGhlIGZpcnN0IHN0ZXAgaXMgdG8gY2VudGVyIHRoZSBkYXRhLiBXZSBzdWJ0cmFjdCB0aGUgbWVhbiBvZiBlYWNoIHZhcmlhYmxlLCBjcmVhdGluZyBhIG5ldyBkYXRhIG1hdHJpeCAkXG1hdGhiZntZfSQ6DQoNCiQkDQpcbWF0aGJme1l9ID0gXG1hdGhiZntYfSAtIFxtYXRoYmZ7MX1cYmFye1xtYXRoYmZ7eH19XlQNCiQkDQoNCndoZXJlICRcbWF0aGJmezF9JCBpcyBhbiAkbiBcdGltZXMgMSQgdmVjdG9yIG9mIG9uZXMuIFRoZSBlbGVtZW50cyBvZiAkXG1hdGhiZntZfSQgYXJlICR5X3tpan0gPSB4X3tpan0gLSBcYmFye3h9X2okLiBGcm9tIHRoaXMgcG9pbnQgZm9yd2FyZCwgd2Ugd29yayB3aXRoIHRoZSBjZW50ZXJlZCBkYXRhICRcbWF0aGJme1l9JCwgZW5zdXJpbmcgJEVbXG1hdGhiZnt5fV0gPSBcbWF0aGJmezB9JC4NCg0KKiozLiBHb2FsIG9mIFByaW5jaXBhbCBDb21wb25lbnQgQW5hbHlzaXMgKFBDQSkqKg0KDQpUaGUgZ29hbCBvZiBQQ0EgaXMgdG8gZmluZCBhIG5ldyBzZXQgb2YgdW5jb3JyZWxhdGVkIHZhcmlhYmxlcyAkXG1hdGhiZnt6fSA9IFt6XzEsIHpfMiwgel8zLCB6XzRdXlQkLCBjYWxsZWQgdGhlIFx0ZXh0YmZ7UHJpbmNpcGFsIENvbXBvbmVudHN9IChQQ3MpLCB3aGljaCBhcmUgbGluZWFyIGNvbWJpbmF0aW9ucyBvZiB0aGUgb3JpZ2luYWwgY2VudGVyZWQgdmFyaWFibGVzICRcbWF0aGJme3l9JC4NCg0KJCQNClxtYXRoYmZ7en0gPSBcbWF0aGJme1d9XlRcbWF0aGJme3l9DQokJA0KDQpUaGUgbWF0cml4ICRcbWF0aGJme1d9JCBpcyBhbiBvcnRob2dvbmFsIG1hdHJpeCAoJFxtYXRoYmZ7V31eVFxtYXRoYmZ7V30gPSBcbWF0aGJme0l9JCkgd2hvc2UgY29sdW1ucyAkXG1hdGhiZnt3fV9pJCBhcmUgdGhlIFx0ZXh0YmZ7bG9hZGluZyB2ZWN0b3JzfS4gVGhlIGNvbXBvbmVudHMgbXVzdCBzYXRpc2Z5Og0KDQoqIFRoZSBmaXJzdCBjb21wb25lbnQsICR6XzEgPSBcbWF0aGJme3d9XzFeVCBcbWF0aGJme3l9JCwgaGFzIHRoZSBtYXhpbXVtIHBvc3NpYmxlIHZhcmlhbmNlLg0KKiBUaGUgJGskLXRoIGNvbXBvbmVudCwgJHpfayA9IFxtYXRoYmZ7d31fa15UIFxtYXRoYmZ7eX0kLCBoYXMgdGhlIG1heGltdW0gcG9zc2libGUgdmFyaWFuY2Ugc3ViamVjdCB0byBiZWluZyB1bmNvcnJlbGF0ZWQgd2l0aCAob3J0aG9nb25hbCB0bykgYWxsIHByZXZpb3VzIGNvbXBvbmVudHMgJHpfMSwgXGRvdHMsIHpfe2stMX0kLg0KIA0KDQoqKjQuIERlcml2YXRpb24gb2YgdGhlIEZpcnN0IFByaW5jaXBhbCBDb21wb25lbnQqKg0KDQpMZXQgJFxtYXRoYmZ7d31fMSQgYmUgdGhlIHZlY3RvciBvZiB3ZWlnaHRzIGZvciB0aGUgZmlyc3QgUEMsICR6XzEgPSBcbWF0aGJme3d9XzFeVCBcbWF0aGJme3l9JC4NClRoZSBzYW1wbGUgdmFyaWFuY2Ugb2YgJHpfMSQgaXMgZ2l2ZW4gYnk6DQoNCiQkDQpcYmVnaW57YWxpZ24qfQ0KXHRleHR7VmFyfSh6XzEpICY9IFx0ZXh0e1Zhcn0oXG1hdGhiZnt3fV8xXlQgXG1hdGhiZnt5fSkgXFwNCiAgICAgICAgICAgICAgICAmPSBFWyhcbWF0aGJme3d9XzFeVCBcbWF0aGJme3l9KShcbWF0aGJme3d9XzFeVCBcbWF0aGJme3l9KV5UXSBccXVhZCBcdGV4dHsoc2luY2V9IEVbXG1hdGhiZnt5fV09XG1hdGhiZnswfSkgXFwNCiAgICAgICAgICAgICAgICAmPSBFW1xtYXRoYmZ7d31fMV5UIFxtYXRoYmZ7eX0gXG1hdGhiZnt5fV5UIFxtYXRoYmZ7d31fMV0gXFwNCiAgICAgICAgICAgICAgICAmPSBcbWF0aGJme3d9XzFeVCBFW1xtYXRoYmZ7eX0gXG1hdGhiZnt5fV5UXSBcbWF0aGJme3d9XzEgXFwNCiAgICAgICAgICAgICAgICAmPSBcbWF0aGJme3d9XzFeVCBcYm9sZHN5bWJvbHtcU2lnbWF9IFxtYXRoYmZ7d31fMQ0KXGVuZHthbGlnbip9DQokJA0KDQoNCkluIHByYWN0aWNlLCB3ZSB1c2UgdGhlIHNhbXBsZSBjb3ZhcmlhbmNlIG1hdHJpeCAkXG1hdGhiZntTfSA9IFxmcmFjezF9e24tMX0gXG1hdGhiZntZfV5UIFxtYXRoYmZ7WX0kLg0KDQpXZSB3aXNoIHRvIG1heGltaXplICRcbWF0aGJme3d9XzFeVCBcbWF0aGJme1N9IFxtYXRoYmZ7d31fMSQgc3ViamVjdCB0byB0aGUgbm9ybWFsaXphdGlvbiBjb25zdHJhaW50ICRcbWF0aGJme3d9XzFeVCBcbWF0aGJme3d9XzEgPSAxJCAodG8gcHJldmVudCB0aGUgdmFyaWFuY2UgZnJvbSBncm93aW5nIGFyYml0cmFyaWx5IGxhcmdlKS4gV2Ugc29sdmUgdGhpcyB1c2luZyB0aGUgbWV0aG9kIG9mIExhZ3JhbmdlIG11bHRpcGxpZXJzLg0KDQpUaGUgTGFncmFuZ2lhbiBpczoNCg0KJCQNClxtYXRoY2Fse0x9KFxtYXRoYmZ7d31fMSwgXGxhbWJkYV8xKSA9IFxtYXRoYmZ7d31fMV5UIFxtYXRoYmZ7U30gXG1hdGhiZnt3fV8xIC0gXGxhbWJkYV8xIChcbWF0aGJme3d9XzFeVCBcbWF0aGJme3d9XzEgLSAxKQ0KJCQNCg0KVGFraW5nIHRoZSBncmFkaWVudCB3aXRoIHJlc3BlY3QgdG8gJFxtYXRoYmZ7d31fMSQgYW5kIHNldHRpbmcgaXQgdG8gemVybzoNCg0KJCQNClxmcmFje1xwYXJ0aWFsIFxtYXRoY2Fse0x9fXtccGFydGlhbCBcbWF0aGJme3d9XzF9ID0gMlxtYXRoYmZ7U31cbWF0aGJme3d9XzEgLSAyXGxhbWJkYV8xIFxtYXRoYmZ7d31fMSA9IDANCiQkDQoNCg0KVGhpcyB5aWVsZHMgdGhlIGtleSBcdGV4dGJme2VpZ2VudmFsdWUgZXF1YXRpb259Og0KDQokJA0KXGJlZ2lue2VxdWF0aW9ufQ0KXG1hdGhiZntTfSBcbWF0aGJme3d9XzEgPSBcbGFtYmRhXzEgXG1hdGhiZnt3fV8xDQpcZW5ke2VxdWF0aW9ufQ0KJCQNCg0KU3Vic3RpdHV0aW5nIHRoZSBhYm92ZSBlcXVhdGlvbiBiYWNrIGludG8gdGhlIHZhcmlhbmNlIGV4cHJlc3Npb246DQoNCiQkDQpcdGV4dHtWYXJ9KHpfMSkgPSBcbWF0aGJme3d9XzFeVCBcbWF0aGJme1N9IFxtYXRoYmZ7d31fMSA9IFxtYXRoYmZ7d31fMV5UIChcbGFtYmRhXzEgXG1hdGhiZnt3fV8xKSA9IFxsYW1iZGFfMSBcbWF0aGJme3d9XzFeVCBcbWF0aGJme3d9XzEgPSBcbGFtYmRhXzENCiQkDQoNClRodXMsIHRoZSB2YXJpYW5jZSBvZiB0aGUgZmlyc3QgcHJpbmNpcGFsIGNvbXBvbmVudCAkel8xJCBpcyB0aGUgZWlnZW52YWx1ZSAkXGxhbWJkYV8xJC4gVG8gbWF4aW1pemUgdGhlIHZhcmlhbmNlLCB3ZSBtdXN0IGNob29zZSB0aGUgXHRleHRiZntlaWdlbnZlY3RvciAkXG1hdGhiZnt3fV8xJCBjb3JyZXNwb25kaW5nIHRvIHRoZSBsYXJnZXN0IGVpZ2VudmFsdWUgb2YgJFxtYXRoYmZ7U30kfS4NCg0KKio1LiBEZXJpdmF0aW9uIG9mIHRoZSBTZWNvbmQgUHJpbmNpcGFsIENvbXBvbmVudCoqDQoNCldlIG5vdyBzZWVrIHRoZSBzZWNvbmQgY29tcG9uZW50ICR6XzIgPSBcbWF0aGJme3d9XzJeVCBcbWF0aGJme3l9JCB0aGF0IGhhcyBtYXhpbXVtIHZhcmlhbmNlLCBzdWJqZWN0IHRvICRcbWF0aGJme3d9XzJeVCBcbWF0aGJme3d9XzIgPSAxJCBhbmQgJFxtYXRoYmZ7d31fMl5UIFxtYXRoYmZ7d31fMSA9IDAkIChlbnN1cmluZyAkel8yJCBpcyB1bmNvcnJlbGF0ZWQgd2l0aCAkel8xJCkuDQoNClRoZSBMYWdyYW5naWFuIGZvciB0aGlzIHByb2JsZW0gaXM6DQoNCiQkDQpcbWF0aGNhbHtMfShcbWF0aGJme3d9XzIsIFxsYW1iZGFfMiwgXHBoaSkgPSBcbWF0aGJme3d9XzJeVCBcbWF0aGJme1N9IFxtYXRoYmZ7d31fMiAtIFxsYW1iZGFfMiAoXG1hdGhiZnt3fV8yXlQgXG1hdGhiZnt3fV8yIC0gMSkgLSBccGhpIChcbWF0aGJme3d9XzJeVCBcbWF0aGJme3d9XzEpDQokJA0KDQpUYWtpbmcgdGhlIGdyYWRpZW50IHdpdGggcmVzcGVjdCB0byAkXG1hdGhiZnt3fV8yJCBhbmQgc2V0dGluZyBpdCB0byB6ZXJvOg0KDQokJA0KXGZyYWN7XHBhcnRpYWwgXG1hdGhjYWx7TH19e1xwYXJ0aWFsIFxtYXRoYmZ7d31fMn0gPSAyXG1hdGhiZntTfVxtYXRoYmZ7d31fMiAtIDJcbGFtYmRhXzIgXG1hdGhiZnt3fV8yIC0gXHBoaSBcbWF0aGJme3d9XzEgPSAwDQokJA0KDQpNdWx0aXBseSB0aGlzIGVxdWF0aW9uIG9uIHRoZSBsZWZ0IGJ5ICRcbWF0aGJme3d9XzFeVCQ6DQoNCiQkDQoyXG1hdGhiZnt3fV8xXlRcbWF0aGJme1N9XG1hdGhiZnt3fV8yIC0gMlxsYW1iZGFfMiBcbWF0aGJme3d9XzFeVFxtYXRoYmZ7d31fMiAtIFxwaGkgXG1hdGhiZnt3fV8xXlRcbWF0aGJme3d9XzEgPSAwDQokJA0KDQpGcm9tIHRoZSBlaWdlbnZhbHVlIGVxdWF0aW9uIGZvciAkXG1hdGhiZnt3fV8xJCwgd2Uga25vdyAkXG1hdGhiZnt3fV8xXlRcbWF0aGJme1N9ID0gXGxhbWJkYV8xIFxtYXRoYmZ7d31fMV5UJC4gVGhlIG9ydGhvZ29uYWxpdHkgY29uc3RyYWludCBnaXZlcyAkXG1hdGhiZnt3fV8xXlRcbWF0aGJme3d9XzI9MCQuIFN1YnN0aXR1dGluZyB0aGVzZToNCg0KJCQNCjJcbGFtYmRhXzEgXG1hdGhiZnt3fV8xXlRcbWF0aGJme3d9XzIgLSAwIC0gXHBoaSAoMSkgPSAwIFxpbXBsaWVzIDJcbGFtYmRhXzEgKDApIC0gXHBoaSA9IDAgXGltcGxpZXMgXHBoaSA9IDANCiQkDQoNCg0KV2l0aCAkXHBoaT0wJCwgdGhlIGdyYWRpZW50IGVxdWF0aW9uIHNpbXBsaWZpZXMgdG86DQoNCiQkDQoyXG1hdGhiZntTfVxtYXRoYmZ7d31fMiAtIDJcbGFtYmRhXzIgXG1hdGhiZnt3fV8yID0gMCBcaW1wbGllcyBcbWF0aGJme1N9IFxtYXRoYmZ7d31fMiA9IFxsYW1iZGFfMiBcbWF0aGJme3d9XzINCiQkDQoNClRoaXMgaXMgYWdhaW4gYW4gZWlnZW52YWx1ZSBlcXVhdGlvbi4gVGhlIHZhcmlhbmNlIG9mICR6XzIkIGlzICRcbGFtYmRhXzIkLiBUbyBtYXhpbWl6ZSB0aGUgdmFyaWFuY2UsIHdlIGNob29zZSB0aGUgZWlnZW52ZWN0b3IgJFxtYXRoYmZ7d31fMiQgY29ycmVzcG9uZGluZyB0byB0aGUgXHRleHRiZntzZWNvbmQgbGFyZ2VzdCBlaWdlbnZhbHVlfSAkXGxhbWJkYV8yJC4gVGhlIG9ydGhvZ29uYWxpdHkgJFxtYXRoYmZ7d31fMl5UIFxtYXRoYmZ7d31fMSA9IDAkIGlzIGF1dG9tYXRpY2FsbHkgc2F0aXNmaWVkIGZvciBkaXN0aW5jdCBlaWdlbnZhbHVlcyBzaW5jZSAkXG1hdGhiZntTfSQgaXMgc3ltbWV0cmljLg0KDQoqKjYuIFN1YnNlcXVlbnQgQ29tcG9uZW50cyBhbmQgRnVsbCBTb2x1dGlvbioqDQoNClRoaXMgcHJvY2VzcyBjb250aW51ZXMgZm9yIGFsbCBmb3VyIGNvbXBvbmVudHMuIFRoZSBzb2x1dGlvbiB0byB0aGUgUENBIHByb2JsZW0gaXMgZm91bmQgYnkgcGVyZm9ybWluZyB0aGUgXHRleHRiZntlaWdlbmRlY29tcG9zaXRpb259IG9mIHRoZSBzYW1wbGUgY292YXJpYW5jZSBtYXRyaXggJFxtYXRoYmZ7U30kOg0KDQokJA0KXG1hdGhiZntTfSA9IFxtYXRoYmZ7V30gXGJvbGRzeW1ib2x7XExhbWJkYX0gXG1hdGhiZntXfV5UDQokJA0KDQp3aGVyZToNCg0KKiAgJFxib2xkc3ltYm9se1xMYW1iZGF9JCBpcyBhIGRpYWdvbmFsIG1hdHJpeCBjb250YWluaW5nIHRoZSBlaWdlbnZhbHVlcyBpbiBkZXNjZW5kaW5nIG9yZGVyOiAkXGxhbWJkYV8xIFxnZSBcbGFtYmRhXzIgXGdlIFxsYW1iZGFfMyBcZ2UgXGxhbWJkYV80IFxnZSAwJC4NCiogICRcbWF0aGJme1d9ID0gW1xtYXRoYmZ7d31fMSwgXG1hdGhiZnt3fV8yLCBcbWF0aGJme3d9XzMsIFxtYXRoYmZ7d31fNF0kIGlzIGFuIG9ydGhvZ29uYWwgbWF0cml4IHdob3NlIGNvbHVtbnMgYXJlIHRoZSBjb3JyZXNwb25kaW5nIGVpZ2VudmVjdG9ycy4NCg0KDQpUaGUgcHJpbmNpcGFsIGNvbXBvbmVudHMgZm9yIGFuIGluZGl2aWR1YWwgd2l0aCBjZW50ZXJlZCByZXNwb25zZSB2ZWN0b3IgJFxtYXRoYmZ7eX0kIGFyZSB0aGVuIGNvbXB1dGVkIGFzOg0KDQokJA0KXG1hdGhiZnt6fSA9IFxtYXRoYmZ7V31eVCBcbWF0aGJme3l9DQokJA0KDQpUaGUgJGskLXRoIFBDIHNjb3JlIGlzICR6X2sgPSBcbWF0aGJme3d9X2teVCBcbWF0aGJme3l9JC4NCg0KKio3LiBWYXJpYW5jZSBFeHBsYWluZWQqKg0KDQpUaGUgdG90YWwgdmFyaWFuY2UgaW4gdGhlIG9yaWdpbmFsIGRhdGEgaXMgdGhlIHN1bSBvZiB0aGUgdmFyaWFuY2VzIG9mIHRoZSBjZW50ZXJlZCB2YXJpYWJsZXMsIHdoaWNoIGlzIHRoZSB0cmFjZSBvZiAkXG1hdGhiZntTfSQuDQoNCiQkDQpcdGV4dHtUb3RhbCBWYXJpYW5jZX0gPSBcdGV4dHt0cn0oXG1hdGhiZntTfSkgPSBzX3sxMX1eMiArIHNfezIyfV4yICsgc197MzN9XjIgKyBzX3s0NH1eMg0KJCQNCg0KRm9yIGEgc3ltbWV0cmljIG1hdHJpeCwgdGhpcyBpcyBhbHNvIGVxdWFsIHRvIHRoZSBzdW0gb2YgaXRzIGVpZ2VudmFsdWVzOg0KDQokJA0KXHRleHR7VG90YWwgVmFyaWFuY2V9ID0gXGxhbWJkYV8xICsgXGxhbWJkYV8yICsgXGxhbWJkYV8zICsgXGxhbWJkYV80DQokJA0KVGhlIHByb3BvcnRpb24gb2YgdG90YWwgdmFyaWFuY2UgZXhwbGFpbmVkIGJ5IHRoZSAkayQtdGggcHJpbmNpcGFsIGNvbXBvbmVudCBpczoNCg0KJCQNClx0ZXh0e1Byb3BvcnRpb259X2sgPSBcZnJhY3tcbGFtYmRhX2t9e1xzdW1fe2k9MX1eezR9IFxsYW1iZGFfaX0NCiQkDQoNCg0KVGhlIGN1bXVsYXRpdmUgdmFyaWFuY2UgZXhwbGFpbmVkIGJ5IHRoZSBmaXJzdCAkbSQgY29tcG9uZW50cyBpczoNCg0KJCQNClx0ZXh0e0N1bXVsYXRpdmV9X20gPSBcZnJhY3tcc3VtX3tpPTF9XnttfSBcbGFtYmRhX2l9e1xzdW1fe2k9MX1eezR9IFxsYW1iZGFfaX0NCiQkDQoNCioqOC4gSW50ZXJwcmV0YXRpb24gaW4gb3VyIENvbnRleHQqKg0KDQpJbiB0aGUgY29udGV4dCBvZiBvdXIgbWF0aCBldmFsdWF0aW9uIGFueGlldHkgcXVlc3Rpb25uYWlyZToNCg0KKiAgVGhlIGxvYWRpbmcgdmVjdG9yICRcbWF0aGJme3d9XzEgPSBbd197MTF9LCB3X3sxMn0sIHdfezEzfSwgd197MTR9XV5UJCByZXZlYWxzIGhvdyB0aGUgb3JpZ2luYWwgaXRlbXMgY29tYmluZSB0byBmb3JtIHRoZSBwcmltYXJ5IGxhdGVudCBkaW1lbnNpb24gb2YgYW54aWV0eS4gRm9yIGV4YW1wbGUsIGlmIGFsbCBsb2FkaW5ncyBhcmUgcG9zaXRpdmUgYW5kIHNpbWlsYXIsICR6XzEkIG1pZ2h0IHJlcHJlc2VudCBcdGV4dGJme0dlbmVyYWwgTWF0aCBFdmFsdWF0aW9uIEFueGlldHl9Lg0KDQoqICBUaGUgc2Vjb25kIGNvbXBvbmVudCAkXG1hdGhiZnt3fV8yJCBtaWdodCBjb250cmFzdCBkaWZmZXJlbnQgdHlwZXMgb2YgYW54aWV0eS4gRm9yIGluc3RhbmNlLCBpZiAkd197MjF9JCBhbmQgJHdfezIyfSQgKHRlc3QtcmVsYXRlZCkgYXJlIHBvc2l0aXZlIHdoaWxlICR3X3syM30kIGFuZCAkd197MjR9JCAocG9wIHF1aXovaG9tZXdvcmspIGFyZSBuZWdhdGl2ZSwgJHpfMiQgbWlnaHQgcmVwcmVzZW50IFx0ZXh0YmZ7VGVzdCBBbnhpZXR5IHZzLiBTcG9udGFuZW91cyBFdmFsdWF0aW9uIEFueGlldHl9Lg0KKiAgQnkgZXhhbWluaW5nIHRoZSBsb2FkaW5ncywgd2UgY2FuIGludGVycHJldCB0aGUgdW5kZXJseWluZyBwc3ljaG9sb2dpY2FsIGNvbnN0cnVjdHMgdGhhdCBkcml2ZSB0aGUgY29ycmVsYXRpb25zIGJldHdlZW4gdGhlIGZvdXIgcXVlc3Rpb25uYWlyZSBpdGVtcy4NCg0KDQojIyBDb25maXJtYXRpY2UgRmFjdG9yIEFuYWx5c2lzIChDRkEpDQoNCg0KDQpUaGlzIGFwcGVuZGl4IHByb3ZpZGVzIGEgZGV0YWlsZWQgbWF0aGVtYXRpY2FsIGRlcml2YXRpb24gb2YgYSBDb25maXJtYXRvcnkgRmFjdG9yIEFuYWx5c2lzIChDRkEpIG1vZGVsLiBUaGUgb2JzZXJ2ZWQgdmFyaWFibGVzIGFyZSBuaW5lIGl0ZW1zIHJlbGF0ZWQgdG8gbWF0aGVtYXRpY2FsIGFueGlldHksIHdoaWNoIGFyZSBoeXBvdGhlc2l6ZWQgdG8gbG9hZCBvbnRvIHR3byBsYXRlbnQgZmFjdG9yczogXHRleHRiZntUZXN0IEFueGlldHkgKFRBKX0gYW5kIFx0ZXh0YmZ7TGVhcm5pbmcgQW54aWV0eSAoTEEpfS4NCg0KDQoqKjEuIExhdGVudCBGYWN0b3JzIGFuZCBPYnNlcnZlZCBWYXJpYWJsZXMqKg0KDQpXZSBkZWZpbmUgdHdvIGxhdGVudCBmYWN0b3JzOg0KDQoqICRcZXRhXzEkOiBUZXN0IEFueGlldHkgKFRBKQ0KKiAkXGV0YV8yJDogTGVhcm5pbmcgQW54aWV0eSAoTEEpDQoNCg0KV2UgaGF2ZSBuaW5lIG9ic2VydmVkIHZhcmlhYmxlcyAoaXRlbXMvcXVlc3Rpb25zKSwgJHlfMSQgdG8gJHlfOSQ6DQoNCiogJHlfMSQ6IEhhdmluZyB0byB1c2UgdGFibGVzIGluIHRoZSBiYWNrIG9mIGEgbWF0aCBib29rLg0KKiAkeV8yJDogVGhpbmtpbmcgYWJvdXQgYSBtYXRoIHRlc3QgdGhlIGRheSBiZWZvcmUgeW91IHRha2UgaXQuDQoqICR5XzMkOiBXYXRjaGluZyB0aGUgdGVhY2hlciB3b3JrIG91dCBhIG1hdGggcHJvYmxlbSBvbiB0aGUgYm9hcmQuDQoqICR5XzQkOiBUYWtpbmcgYSBtYXRoIHRlc3QuDQoqICR5XzUkOiBCZWluZyBnaXZlbiBhIGhvbWV3b3JrIGFzc2lnbm1lbnQgb2YgbWFueSBkaWZmaWN1bHQgcHJvYmxlbXMgdGhhdCBpcyBkdWUgZm9yIHRoZSBuZXh0IGNsYXNzIG1lZXRpbmcuDQoqICR5XzYkOiBMaXN0ZW5pbmcgdG8gYSBsZWN0dXJlIGluIG1hdGggY2xhc3MuDQoqICR5XzckOiBMaXN0ZW5pbmcgdG8gYW5vdGhlciBzdHVkZW50IGV4cGxhaW4gaG93IHRvIGRvIGEgbWF0aCBwcm9ibGVtLg0KKiAkeV84JDogQmVpbmcgZ2l2ZW4gYSBxdWl6IG9uIG1hdGggd2l0aG91dCBrbm93aW5nIGluIGFkdmFuY2UuDQoqICR5XzkkOiBTdGFydGluZyBhIG5ldyBjaGFwdGVyIGluIGEgbWF0aCBib29rLg0KIA0KDQoqKjIuIEZhY3RvciBMb2FkaW5ncyBhbmQgTW9kZWwgU3RydWN0dXJlKioNCg0KV2UgaHlwb3RoZXNpemUgdGhlIGZvbGxvd2luZyBmYWN0b3Igc3RydWN0dXJlOg0KDQoqIEZhY3RvciAkXGV0YV8xJCAoVGVzdCBBbnhpZXR5KSBsb2FkcyBvbiBpdGVtcyAkeV8yJCwgJHlfNCQsICR5XzUkLCBhbmQgJHlfOCQuDQoqIEZhY3RvciAkXGV0YV8yJCAoTGVhcm5pbmcgQW54aWV0eSkgbG9hZHMgb24gaXRlbXMgJHlfMSQsICR5XzMkLCAkeV82JCwgJHlfNyQsIGFuZCAkeV85JC4NCg0KDQpUaGUgZnVuZGFtZW50YWwgZXF1YXRpb24gZm9yIGEgQ0ZBIG1vZGVsIGZvciBhIHNpbmdsZSBvYnNlcnZlZCB2YXJpYWJsZSAkeV9pJCBpczoNCg0KJCQNCnlfaSA9IFxudV9pICsgXGxhbWJkYV97aTF9IFxldGFfMSArIFxsYW1iZGFfe2kyfSBcZXRhXzIgKyBcZXBzaWxvbl9pDQokJA0KDQp3aGVyZToNCg0KKiAkXG51X2kkIGlzIHRoZSBpbnRlcmNlcHQgZm9yIG9ic2VydmVkIHZhcmlhYmxlICR5X2kkLg0KKiAkXGxhbWJkYV97aTF9JCBpcyB0aGUgZmFjdG9yIGxvYWRpbmcgb2YgJHlfaSQgb24gbGF0ZW50IGZhY3RvciAkXGV0YV8xJC4NCiogJFxsYW1iZGFfe2kyfSQgaXMgdGhlIGZhY3RvciBsb2FkaW5nIG9mICR5X2kkIG9uIGxhdGVudCBmYWN0b3IgJFxldGFfMiQuDQoqICRcZXBzaWxvbl9pJCBpcyB0aGUgdW5pcXVlIGZhY3RvciAobWVhc3VyZW1lbnQgZXJyb3IpIGZvciAkeV9pJC4NCg0KDQoqKjMuIFRoZSBNZWFzdXJlbWVudCBNb2RlbCBpbiBNYXRyaXggRm9ybSoqDQoNClRoZSBtb2RlbCBmb3IgYWxsIG5pbmUgb2JzZXJ2ZWQgdmFyaWFibGVzIGNhbiBiZSB3cml0dGVuIGNvbXBhY3RseSBpbiBtYXRyaXggZm9ybS4gV2UgZGVmaW5lIHRoZSBmb2xsb3dpbmcgdmVjdG9ycyBhbmQgbWF0cmljZXM6DQoNCiogJFxtYXRoYmZ7eX0gPSAoeV8xLCB5XzIsIFxkb3RzLCB5XzkpXlQkIGlzIGEgJDkgXHRpbWVzIDEkIHZlY3RvciBvZiBvYnNlcnZlZCB2YXJpYWJsZXMuDQoqICRcYm9sZHN5bWJvbHtcbnV9ID0gKFxudV8xLCBcbnVfMiwgXGRvdHMsIFxudV85KV5UJCBpcyBhICQ5IFx0aW1lcyAxJCB2ZWN0b3Igb2YgaW50ZXJjZXB0cy4NCiogJFxib2xkc3ltYm9se1xldGF9ID0gKFxldGFfMSwgXGV0YV8yKV5UJCBpcyBhICQyIFx0aW1lcyAxJCB2ZWN0b3Igb2YgbGF0ZW50IGZhY3RvcnMuDQoqICRcYm9sZHN5bWJvbHtcTGFtYmRhfSQgaXMgYSAkOSBcdGltZXMgMiQgbWF0cml4IG9mIGZhY3RvciBsb2FkaW5ncyAkXGxhbWJkYV97aWp9JC4NCiogJFxib2xkc3ltYm9se1xlcHNpbG9ufSA9IChcZXBzaWxvbl8xLCBcZXBzaWxvbl8yLCBcZG90cywgXGVwc2lsb25fOSleVCQgaXMgYSAkOSBcdGltZXMgMSQgdmVjdG9yIG9mIG1lYXN1cmVtZW50IGVycm9ycy4NCg0KDQpUaGUgZnVsbCBtZWFzdXJlbWVudCBtb2RlbCBpczoNCg0KJCQNClxtYXRoYmZ7eX0gPSBcYm9sZHN5bWJvbHtcbnV9ICsgXGJvbGRzeW1ib2x7XExhbWJkYX0gXGJvbGRzeW1ib2x7XGV0YX0gKyBcYm9sZHN5bWJvbHtcZXBzaWxvbn0NCiQkDQoNCkdpdmVuIG91ciBoeXBvdGhlc2l6ZWQgZmFjdG9yIHN0cnVjdHVyZSwgdGhlIGxvYWRpbmcgbWF0cml4ICRcYm9sZHN5bWJvbHtcTGFtYmRhfSQgaGFzIGEgc3BlY2lmaWMgZm9ybSB3aXRoIG1hbnkgZWxlbWVudHMgZml4ZWQgdG8gemVyby4gVG8gZW5zdXJlIG1vZGVsIGlkZW50aWZpY2F0aW9uLCB3ZSBuZWVkIHRvIHNldCB0aGUgc2NhbGUgb2YgZWFjaCBsYXRlbnQgdmFyaWFibGUuIFRoaXMgaXMgdHlwaWNhbGx5IGRvbmUgYnkgXHRleHRiZntmYWN0b3Igc3RhbmRhcmRpemF0aW9ufSwgd2hlcmUgdGhlIHZhcmlhbmNlIG9mIHRoZSBsYXRlbnQgZmFjdG9yIGlzIGZpeGVkIHRvIDEsIG9yIGJ5IFx0ZXh0YmZ7bWFya2VyIHZhcmlhYmxlfSBtZXRob2QsIHdoZXJlIG9uZSBsb2FkaW5nIHBlciBmYWN0b3IgaXMgZml4ZWQgdG8gMS4gV2Ugd2lsbCB1c2UgdGhlIGxhdHRlci4NCg0KTGV0IHVzIGRlZmluZToNCg0KKiAkeV8yJCBhcyB0aGUgbWFya2VyIHZhcmlhYmxlIGZvciAkXGV0YV8xJCAoVGVzdCBBbnhpZXR5KSwgc28gJFxsYW1iZGFfezIxfSA9IDEkLg0KKiAkeV8xJCBhcyB0aGUgbWFya2VyIHZhcmlhYmxlIGZvciAkXGV0YV8yJCAoTGVhcm5pbmcgQW54aWV0eSksIHNvICRcbGFtYmRhX3sxMn0gPSAxJC4NCg0KDQpUaGUgJFxib2xkc3ltYm9se1xMYW1iZGF9JCBtYXRyaXggaXMgdGhlbjoNCg0KJCQNClxib2xkc3ltYm9se1xMYW1iZGF9ID0NClxiZWdpbntibWF0cml4fQ0KMCAmIDEgXFwgICAgICAgICAgICAgICUgeTEgbG9hZHMgb24gZXRhMiAoTEEpDQoxICYgMCBcXCAgICAgICAgICAgICAgJSB5MiBsb2FkcyBvbiBldGExIChUQSkNCjAgJiBcbGFtYmRhX3szMn0gXFwgICAlIHkzIGxvYWRzIG9uIGV0YTIgKExBKQ0KXGxhbWJkYV97NDF9ICYgMCBcXCAgICUgeTQgbG9hZHMgb24gZXRhMSAoVEEpDQpcbGFtYmRhX3s1MX0gJiAwIFxcICAgJSB5NSBsb2FkcyBvbiBldGExIChUQSkNCjAgJiBcbGFtYmRhX3s2Mn0gXFwgICAlIHk2IGxvYWRzIG9uIGV0YTIgKExBKQ0KMCAmIFxsYW1iZGFfezcyfSBcXCAgICUgeTcgbG9hZHMgb24gZXRhMiAoTEEpDQpcbGFtYmRhX3s4MX0gJiAwIFxcICAgJSB5OCBsb2FkcyBvbiBldGExIChUQSkNCjAgJiBcbGFtYmRhX3s5Mn0gXFwgICAlIHk5IGxvYWRzIG9uIGV0YTIgKExBKQ0KXGVuZHtibWF0cml4fQ0KJCQNCg0KDQoqKjQuIE1vZGVsIEFzc3VtcHRpb25zKioNCg0KVGhlIENGQSBtb2RlbCByZWxpZXMgb24gc2V2ZXJhbCBrZXkgYXNzdW1wdGlvbnM6DQoNCiogVGhlIGVycm9ycyBoYXZlIGEgbWVhbiBvZiB6ZXJvOiAkRShcYm9sZHN5bWJvbHtcZXBzaWxvbn0pID0gXG1hdGhiZnswfSQuDQogICAgXGl0ZW0gVGhlIGVycm9ycyBhcmUgdW5jb3JyZWxhdGVkIHdpdGggdGhlIGZhY3RvcnM6ICRcbWF0aHJte0Nvdn0oXGJvbGRzeW1ib2x7XGV0YX0sIFxib2xkc3ltYm9se1xlcHNpbG9ufSkgPSBcbWF0aGJmezB9JC4NCiAgICANCiogVGhlIGVycm9ycyBtYXkgYmUgY29ycmVsYXRlZCB3aXRoIGVhY2ggb3RoZXIsIGJ1dCBpbiBhIGJhc2ljIG1vZGVsLCB3ZSBvZnRlbiBhc3N1bWUgdGhleSBhcmUgdW5jb3JyZWxhdGVkOiAkXGJvbGRzeW1ib2x7XFRoZXRhfV97XGVwc2lsb259ID0gXG1hdGhybXtDb3Z9KFxib2xkc3ltYm9se1xlcHNpbG9ufSkgPSBcbWF0aHJte2RpYWd9KFx0aGV0YV97MTF9LCBcdGhldGFfezIyfSwgXGRvdHMsIFx0aGV0YV97OTl9KSQsIHdoZXJlICRcdGhldGFfe2lpfSA9IFxtYXRocm17VmFyfShcZXBzaWxvbl9pKSQuDQoNCg0KKio1LiBEZXJpdmF0aW9uIG9mIHRoZSBJbXBsaWVkIENvdmFyaWFuY2UgTWF0cml4KioNCg0KVGhlIGNvcmUgb2YgQ0ZBIGlzIHRvIG1vZGVsIHRoZSBwb3B1bGF0aW9uIGNvdmFyaWFuY2UgbWF0cml4IG9mIHRoZSBvYnNlcnZlZCB2YXJpYWJsZXMsICRcYm9sZHN5bWJvbHtcU2lnbWF9JC4gVGhlIG1vZGVsLWltcGxpZWQgY292YXJpYW5jZSBtYXRyaXgsIGRlbm90ZWQgJFxib2xkc3ltYm9se1xTaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSkkLCBpcyBhIGZ1bmN0aW9uIG9mIHRoZSBtb2RlbCBwYXJhbWV0ZXJzICRcYm9sZHN5bWJvbHtcdGhldGF9JCAobG9hZGluZ3MsIGZhY3RvciB2YXJpYW5jZXMvY292YXJpYW5jZXMsIGVycm9yIHZhcmlhbmNlcykuDQoNCkxldCAkXGJvbGRzeW1ib2x7XFBzaX0kIGJlIHRoZSAkMiBcdGltZXMgMiQgY292YXJpYW5jZSBtYXRyaXggb2YgdGhlIGxhdGVudCBmYWN0b3JzOg0KDQokJA0KXGJvbGRzeW1ib2x7XFBzaX0gPSBcbWF0aHJte0Nvdn0oXGJvbGRzeW1ib2x7XGV0YX0pID0NClxiZWdpbntibWF0cml4fQ0KXHBzaV97MTF9ICYgXHBzaV97MTJ9IFxcDQpccHNpX3syMX0gJiBccHNpX3syMn0NClxlbmR7Ym1hdHJpeH0NCj0NClxiZWdpbntibWF0cml4fQ0KXG1hdGhybXtWYXJ9KFxldGFfMSkgJiBcbWF0aHJte0Nvdn0oXGV0YV8xLCBcZXRhXzIpIFxcDQpcbWF0aHJte0Nvdn0oXGV0YV8xLCBcZXRhXzIpICYgXG1hdGhybXtWYXJ9KFxldGFfMikNClxlbmR7Ym1hdHJpeH0NCiQkDQoNCg0KDQpUaGUgaW1wbGllZCBjb3ZhcmlhbmNlIG1hdHJpeCAkXGJvbGRzeW1ib2x7XFNpZ21hfShcYm9sZHN5bWJvbHtcdGhldGF9KSQgaXMgZGVyaXZlZCBhcyBmb2xsb3dzOg0KDQokJA0KXGJlZ2lue2FsaWduKn0NClxib2xkc3ltYm9se1xTaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSkgJj0gXG1hdGhybXtDb3Z9KFxtYXRoYmZ7eX0pIFxcDQomPSBcbWF0aHJte0Nvdn0oXGJvbGRzeW1ib2x7XG51fSArIFxib2xkc3ltYm9se1xMYW1iZGF9XGJvbGRzeW1ib2x7XGV0YX0gKyBcYm9sZHN5bWJvbHtcZXBzaWxvbn0pIFxcDQomPSBcbWF0aHJte0Nvdn0oXGJvbGRzeW1ib2x7XExhbWJkYX1cYm9sZHN5bWJvbHtcZXRhfSArIFxib2xkc3ltYm9se1xlcHNpbG9ufSkgXHF1YWQgXHRleHR7KHNpbmNlIH0gXGJvbGRzeW1ib2x7XG51fSBcdGV4dHsgaXMgYSBjb25zdGFudCl9IFxcDQomPSBcbWF0aHJte0Nvdn0oXGJvbGRzeW1ib2x7XExhbWJkYX1cYm9sZHN5bWJvbHtcZXRhfSkgKyBcbWF0aHJte0Nvdn0oXGJvbGRzeW1ib2x7XGVwc2lsb259KSArIFxtYXRocm17Q292fShcYm9sZHN5bWJvbHtcTGFtYmRhfVxib2xkc3ltYm9se1xldGF9LCBcYm9sZHN5bWJvbHtcZXBzaWxvbn0pICsgXG1hdGhybXtDb3Z9KFxib2xkc3ltYm9se1xlcHNpbG9ufSwgXGJvbGRzeW1ib2x7XExhbWJkYX1cYm9sZHN5bWJvbHtcZXRhfSkNClxlbmR7YWxpZ24qfQ0KJCQNCg0KDQoNClVzaW5nIGFzc3VtcHRpb24gMiAoJFxtYXRocm17Q292fShcYm9sZHN5bWJvbHtcZXRhfSwgXGJvbGRzeW1ib2x7XGVwc2lsb259KSA9IFxtYXRoYmZ7MH0kKSwgdGhlIGNyb3NzLXRlcm1zIHZhbmlzaDoNCg0KJCQNClxtYXRocm17Q292fShcYm9sZHN5bWJvbHtcTGFtYmRhfVxib2xkc3ltYm9se1xldGF9LCBcYm9sZHN5bWJvbHtcZXBzaWxvbn0pID0gXGJvbGRzeW1ib2x7XExhbWJkYX0gXG1hdGhybXtDb3Z9KFxib2xkc3ltYm9se1xldGF9LCBcYm9sZHN5bWJvbHtcZXBzaWxvbn0pID0gXG1hdGhiZnswfSwgXHF1YWQgXG1hdGhybXtDb3Z9KFxib2xkc3ltYm9se1xlcHNpbG9ufSwgXGJvbGRzeW1ib2x7XExhbWJkYX1cYm9sZHN5bWJvbHtcZXRhfSkgPSBcbWF0aGJmezB9DQokJA0KDQoNClRoZXJlZm9yZSwNCg0KJCQNClxiZWdpbnthbGlnbip9DQpcYm9sZHN5bWJvbHtcU2lnbWF9KFxib2xkc3ltYm9se1x0aGV0YX0pICY9IFxtYXRocm17Q292fShcYm9sZHN5bWJvbHtcTGFtYmRhfVxib2xkc3ltYm9se1xldGF9KSArIFxtYXRocm17Q292fShcYm9sZHN5bWJvbHtcZXBzaWxvbn0pIFxcDQomPSBcYm9sZHN5bWJvbHtcTGFtYmRhfSBcbWF0aHJte0Nvdn0oXGJvbGRzeW1ib2x7XGV0YX0pIFxib2xkc3ltYm9se1xMYW1iZGF9XlQgKyBcYm9sZHN5bWJvbHtcVGhldGF9X3tcZXBzaWxvbn0gXFwNCiY9IFxib2xkc3ltYm9se1xMYW1iZGF9IFxib2xkc3ltYm9se1xQc2l9IFxib2xkc3ltYm9se1xMYW1iZGF9XlQgKyBcYm9sZHN5bWJvbHtcVGhldGF9X3tcZXBzaWxvbn0NClxlbmR7YWxpZ24qfQ0KJCQNCg0KDQpUaGlzIGlzIHRoZSBmdW5kYW1lbnRhbCBlcXVhdGlvbiBmb3IgdGhlIGltcGxpZWQgY292YXJpYW5jZSBtYXRyaXggaW4gQ0ZBOg0KDQokJA0KXGJveGVke1xib2xkc3ltYm9se1xTaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSkgPSBcYm9sZHN5bWJvbHtcTGFtYmRhfSBcYm9sZHN5bWJvbHtcUHNpfSBcYm9sZHN5bWJvbHtcTGFtYmRhfV5UICsgXGJvbGRzeW1ib2x7XFRoZXRhfV97XGVwc2lsb259fQ0KJCQNCg0KKio2LiBQYXJhbWV0ZXIgRXN0aW1hdGlvbiBhbmQgTW9kZWwgSWRlbnRpZmljYXRpb24qKg0KDQpUaGUgZ29hbCBvZiBlc3RpbWF0aW9uIGlzIHRvIGZpbmQgcGFyYW1ldGVyIHZhbHVlcyAkXGhhdHtcYm9sZHN5bWJvbHtcdGhldGF9fSQgc3VjaCB0aGF0ICRcYm9sZHN5bWJvbHtcU2lnbWF9KFxoYXR7XGJvbGRzeW1ib2x7XHRoZXRhfX0pJCBpcyBhcyBjbG9zZSBhcyBwb3NzaWJsZSB0byB0aGUgc2FtcGxlIGNvdmFyaWFuY2UgbWF0cml4ICRcbWF0aGJme1N9JCBvYnRhaW5lZCBmcm9tIHRoZSBkYXRhLg0KDQpGb3IgaWRlbnRpZmljYXRpb24sIHRoZSBudW1iZXIgb2YgZnJlZSBwYXJhbWV0ZXJzICR0JCBtdXN0IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byB0aGUgbnVtYmVyIG9mIG5vbi1yZWR1bmRhbnQgZWxlbWVudHMgaW4gJFxtYXRoYmZ7U30kLCB3aGljaCBpcyAkXGZyYWN7cChwKzEpfXsyfSQgd2hlcmUgJHAkIGlzIHRoZSBudW1iZXIgb2Ygb2JzZXJ2ZWQgdmFyaWFibGVzICgkcD05JCkuDQoNCkxldCdzIGNvdW50IG91ciBmcmVlIHBhcmFtZXRlcnMgJHQkOg0KDQoqICoqRmFjdG9yIExvYWRpbmdzKiogKCRcYm9sZHN5bWJvbHtcTGFtYmRhfSQpfTogV2UgZml4ZWQgJFxsYW1iZGFfezIxfSQgYW5kICRcbGFtYmRhX3sxMn0kIHRvIDEuIFdlIGhhdmUgNyBmcmVlIGxvYWRpbmdzOiAkXGxhbWJkYV97MzJ9JCwgJFxsYW1iZGFfezQxfSQsICRcbGFtYmRhX3s1MX0kLCAkXGxhbWJkYV97NjJ9JCwgJFxsYW1iZGFfezcyfSQsICRcbGFtYmRhX3s4MX0kLCAkXGxhbWJkYV97OTJ9JC4NCg0KKiAqKkxhdGVudCBGYWN0b3IgQ292YXJpYW5jZXMqKiAoJFxib2xkc3ltYm9se1xQc2l9JCl9OiBXZSBoYXZlIDMgZnJlZSBwYXJhbWV0ZXJzOiAkXHBzaV97MTF9JCAodmFyaWFuY2Ugb2YgVEEpLCAkXHBzaV97MjJ9JCAodmFyaWFuY2Ugb2YgTEEpLCBhbmQgJFxwc2lfezEyfSQgKGNvdmFyaWFuY2UgYmV0d2VlbiBUQSBhbmQgTEEpLg0KDQoqICoqRXJyb3IgVmFyaWFuY2VzKiogKCRcYm9sZHN5bWJvbHtcVGhldGF9X3tcZXBzaWxvbn0kKX06IFdlIGhhdmUgOSBmcmVlIHBhcmFtZXRlcnM6ICRcdGhldGFfezExfSwgXHRoZXRhX3syMn0sIFxkb3RzLCBcdGhldGFfezk5fSQuDQoNCg0KVG90YWwgZnJlZSBwYXJhbWV0ZXJzOiAkdCA9IDcgKyAzICsgOSA9IDE5JC4NCg0KVGhlIG51bWJlciBvZiBub24tcmVkdW5kYW50IGVsZW1lbnRzIGluICRcbWF0aGJme1N9JCBpcyAkXGZyYWN7OSBcdGltZXMgKDkrMSl9ezJ9ID0gNDUkLg0KDQpTaW5jZSAkNDUgPiAxOSQsIHRoZSBtb2RlbCBpcyBcdGV4dGJme292ZXItaWRlbnRpZmllZH0gd2l0aCAkZGYgPSA0NSAtIDE5ID0gMjYkIGRlZ3JlZXMgb2YgZnJlZWRvbS4gVGhpcyBpcyBhIG5lY2Vzc2FyeSBjb25kaXRpb24gZm9yIGlkZW50aWZpY2F0aW9uLCBhbmQgd2l0aCB0aGUgc2NhbGluZyBjb25zdHJhaW50cyB3ZSBwbGFjZWQsIHRoZSBtb2RlbCBpcyBpZGVudGlmaWVkLg0KDQoqKjcuIENvbmNsdXNpb24qKg0KDQpUaGlzIGRlcml2YXRpb24gaGFzIG91dGxpbmVkIHRoZSBjb21wbGV0ZSBtYXRoZW1hdGljYWwgc2V0dXAgZm9yIGEgdHdvLWZhY3RvciBDRkEgbW9kZWwgb2YgbWF0aGVtYXRpY2FsIGFueGlldHkuIFRoZSBtb2RlbCBwb3NpdHMgdGhhdCB0aGUgY292YXJpYXRpb24gYW1vbmcgdGhlIG5pbmUgb2JzZXJ2ZWQgaXRlbXMgY2FuIGJlIGV4cGxhaW5lZCBieSB0d28gY29ycmVsYXRlZCBsYXRlbnQgZmFjdG9ycy4gVGhlIG5leHQgc3RlcCB3b3VsZCBiZSB0byB1c2UgYW4gZXN0aW1hdGlvbiBhbGdvcml0aG0gKGUuZy4sIE1heGltdW0gTGlrZWxpaG9vZCkgdG8gZmluZCB0aGUgcGFyYW1ldGVyIHZhbHVlcyB0aGF0IG1pbmltaXplIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gJFxib2xkc3ltYm9se1xTaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSkkIGFuZCB0aGUgc2FtcGxlIGNvdmFyaWFuY2UgbWF0cml4ICRcbWF0aGJme1N9JCwgYW5kIHRoZW4gYXNzZXNzIHRoZSBtb2RlbCdzIGZpdCB0byB0aGUgZGF0YS4NCg0KDQoNCg0KDQojIyBNYXRoZW1hdGljYWwgRm9ybXVsYXRpb24gb2YgU0VNIE1vZGVsIA0KDQoNCioqMS4gTW9kZWwgU3BlY2lmaWNhdGlvbioqDQoNCkxldCB0aGUgbW9kZWwgY29uc2lzdCBvZiB0aGUgZm9sbG93aW5nIGNvbXBvbmVudHM6DQoNCg0KKiAqKkV4b2dlbm91cyBsYXRlbnQgdmFyaWFibGVzKio6ICRcYm9sZHN5bWJvbHtceGl9ID0gKFx4aV8xLCBceGlfMileVCQsIHdoZXJlOg0KICArICRceGlfMSQ6IFRlYWNoZXItY2VudGVyZWQNCiAgKyAkXHhpXzIkOiBTdHVkZW50LWNlbnRlcmVkDQoqICoqRW5kb2dlbm91cyBsYXRlbnQgdmFyaWFibGVzKio6ICRcYm9sZHN5bWJvbHtcZXRhfSA9IChcZXRhXzEsIFxldGFfMileVCQsIHdoZXJlOg0KICArICRcZXRhXzEkOiBNYXRoIEV2YWx1YXRpb24gQW54aWV0eSAoTUVBKQ0KICArICRcZXRhXzIkOiBNYXRoIExlYXJuaW5nIEFueGlldHkgKE1MQSkNCiogKipPYnNlcnZlZCBpbmRpY2F0b3JzIGZvciBUZWFjaGVyLWNlbnRlcmVkKio6ICRcbWF0aGJme3h9XzEgPSAoeF8xLCB4XzIsIHhfMywgeF80KV5UJCB3aGVyZToNCiAgKyAkeF8xJDogRGVkdWN0aXZlDQogICsgJHhfMiQ6IExlY3R1cmUNCiAgKyAkeF8zJDogRGVtb25zdHJhdGlvbg0KICArICR4XzQkOiBSZXBldGl0aXZlDQoqICoqT2JzZXJ2ZWQgaW5kaWNhdG9ycyBmb3IgU3R1ZGVudC1jZW50ZXJlZCoqOiAkXG1hdGhiZnt4fV8yID0gKHhfNSwgeF82LCB4XzcpXlQkIHdoZXJlOg0KICArICR4XzUkOiBDb29wZXJhdGl2ZQ0KICArICR4XzYkOiBJbmR1Y3RpdmUNCiAgKyAkeF83JDogSW50ZWdyYXRpdmUNCiogKipPYnNlcnZlZCBpbmRpY2F0b3JzIGZvciBNRUEqKjogJFxtYXRoYmZ7eX1fMSA9ICh5XzEsIHlfMiwgeV8zLCB5XzQpXlQkIChNRUExLU1FQTQpDQoqICoqT2JzZXJ2ZWQgaW5kaWNhdG9ycyBmb3IgTUxBKio6ICRcbWF0aGJme3l9XzIgPSAoeV81LCB5XzYsIHlfNywgeV84LCB5XzkpXlQkIChNTEExLCBNTEEzLCBNTEE2LCBNTEE3LCBNTEE5KQ0KKiAqKkV4b2dlbm91cyBvYnNlcnZlZCB2YXJpYWJsZXMqKjogJFxtYXRoYmZ7d30gPSAod18xLCB3XzIsIHdfMywgd180LCB3XzUpXlQkIHdoZXJlOg0KICArICR3XzEkOiBTZWxmLWVmZmljYWN5DQogICsgJHdfMiQ6IFRlY2hub2xvZ3kNCiAgKyAkd18zJDogRW5nYWdlbWVudA0KICArICR3XzQkOiBHZW5kZXINCiAgKyAkd181JDogUmVzb3VyY2UNCg0KDQoqKjIuIE1lYXN1cmVtZW50IE1vZGVscyoqDQoNCg0KKkZvciBleG9nZW5vdXMgbGF0ZW50IHZhcmlhYmxlczoqDQoNCiQkDQpcYmVnaW57YWxpZ24qfQ0KXG1hdGhiZnt4fSAmPSBcYm9sZHN5bWJvbHtcTGFtYmRhfV94IFxib2xkc3ltYm9se1x4aX0gKyBcYm9sZHN5bWJvbHtcZGVsdGF9IFxcDQpcYmVnaW57Ym1hdHJpeH0NCnhfMSBcXCB4XzIgXFwgeF8zIFxcIHhfNCBcXCB4XzUgXFwgeF82IFxcIHhfNw0KXGVuZHtibWF0cml4fQ0KJj0NClxiZWdpbntibWF0cml4fQ0KXGxhbWJkYV97MSwxfSAmIDAgXFwNClxsYW1iZGFfezIsMX0gJiAwIFxcDQpcbGFtYmRhX3szLDF9ICYgMCBcXA0KXGxhbWJkYV97NCwxfSAmIDAgXFwNCjAgJiBcbGFtYmRhX3s1LDJ9IFxcDQowICYgXGxhbWJkYV97NiwyfSBcXA0KMCAmIFxsYW1iZGFfezcsMn0NClxlbmR7Ym1hdHJpeH0NClxiZWdpbntibWF0cml4fQ0KXHhpXzEgXFwgXHhpXzINClxlbmR7Ym1hdHJpeH0NCisNClxiZWdpbntibWF0cml4fQ0KXGRlbHRhXzEgXFwgXGRlbHRhXzIgXFwgXGRlbHRhXzMgXFwgXGRlbHRhXzQgXFwgXGRlbHRhXzUgXFwgXGRlbHRhXzYgXFwgXGRlbHRhXzcNClxlbmR7Ym1hdHJpeH0NClxlbmR7YWxpZ24qfQ0KJCQNCg0KDQoqRm9yIGVuZG9nZW5vdXMgbGF0ZW50IHZhcmlhYmxlczoqDQoNCiQkDQpcYmVnaW57YWxpZ24qfQ0KXG1hdGhiZnt5fSAmPSBcYm9sZHN5bWJvbHtcTGFtYmRhfV95IFxib2xkc3ltYm9se1xldGF9ICsgXGJvbGRzeW1ib2x7XGVwc2lsb259IFxcDQpcYmVnaW57Ym1hdHJpeH0NCnlfMSBcXCB5XzIgXFwgeV8zIFxcIHlfNCBcXCB5XzUgXFwgeV82IFxcIHlfNyBcXCB5XzggXFwgeV85DQpcZW5ke2JtYXRyaXh9DQomPQ0KXGJlZ2lue2JtYXRyaXh9DQpcbGFtYmRhX3sxLDF9XnkgJiAwIFxcDQpcbGFtYmRhX3syLDF9XnkgJiAwIFxcDQpcbGFtYmRhX3szLDF9XnkgJiAwIFxcDQpcbGFtYmRhX3s0LDF9XnkgJiAwIFxcDQowICYgXGxhbWJkYV97NSwyfV55IFxcDQowICYgXGxhbWJkYV97NiwyfV55IFxcDQowICYgXGxhbWJkYV97NywyfV55IFxcDQowICYgXGxhbWJkYV97OCwyfV55IFxcDQowICYgXGxhbWJkYV97OSwyfV55DQpcZW5ke2JtYXRyaXh9DQpcYmVnaW57Ym1hdHJpeH0NClxldGFfMSBcXCBcZXRhXzINClxlbmR7Ym1hdHJpeH0NCisNClxiZWdpbntibWF0cml4fQ0KXGVwc2lsb25fMSBcXCBcZXBzaWxvbl8yIFxcIFxlcHNpbG9uXzMgXFwgXGVwc2lsb25fNCBcXCBcZXBzaWxvbl81IFxcIA0KXGVwc2lsb25fNiBcXCBcZXBzaWxvbl83IFxcIFxlcHNpbG9uXzggXFwgXGVwc2lsb25fOQ0KXGVuZHtibWF0cml4fQ0KXGVuZHthbGlnbip9DQokJA0KDQoNCg0KKiozLiBTdHJ1Y3R1cmFsIE1vZGVsKioNCg0KVGhlIHJlbGF0aW9uc2hpcHMgYmV0d2VlbiBsYXRlbnQgYW5kIG9ic2VydmVkIHZhcmlhYmxlczoNCg0KJCQNClxiZWdpbnthbGlnbip9DQpcYm9sZHN5bWJvbHtcZXRhfSAmPSBcbWF0aGJme0J9IFxib2xkc3ltYm9se1xldGF9ICsgXGJvbGRzeW1ib2x7XEdhbW1hfSBcYm9sZHN5bWJvbHtceGl9ICsgXGJvbGRzeW1ib2x7XEdhbW1hfV93IFxtYXRoYmZ7d30gKyBcYm9sZHN5bWJvbHtcemV0YX0gXFwNClxiZWdpbntibWF0cml4fQ0KXGV0YV8xIFxcIFxldGFfMg0KXGVuZHtibWF0cml4fQ0KJj0NClxiZWdpbntibWF0cml4fQ0KMCAmIDAgXFwNClxiZXRhX3syMX0gJiAwDQpcZW5ke2JtYXRyaXh9DQpcYmVnaW57Ym1hdHJpeH0NClxldGFfMSBcXCBcZXRhXzINClxlbmR7Ym1hdHJpeH0NCisNClxiZWdpbntibWF0cml4fQ0KXGdhbW1hX3sxMX0gJiBcZ2FtbWFfezEyfSBcXA0KXGdhbW1hX3syMX0gJiBcZ2FtbWFfezIyfQ0KXGVuZHtibWF0cml4fQ0KXGJlZ2lue2JtYXRyaXh9DQpceGlfMSBcXCBceGlfMg0KXGVuZHtibWF0cml4fQ0KKw0KXGJlZ2lue2JtYXRyaXh9DQpcZ2FtbWFfezEzfSAmIFxnYW1tYV97MTR9ICYgXGdhbW1hX3sxNX0gJiBcZ2FtbWFfezE2fSAmIFxnYW1tYV97MTd9IFxcDQpcZ2FtbWFfezIzfSAmIFxnYW1tYV97MjR9ICYgXGdhbW1hX3syNX0gJiBcZ2FtbWFfezI2fSAmIFxnYW1tYV97Mjd9DQpcZW5ke2JtYXRyaXh9DQpcYmVnaW57Ym1hdHJpeH0NCndfMSBcXCB3XzIgXFwgd18zIFxcIHdfNCBcXCB3XzUNClxlbmR7Ym1hdHJpeH0NCisNClxiZWdpbntibWF0cml4fQ0KXHpldGFfMSBcXCBcemV0YV8yDQpcZW5ke2JtYXRyaXh9DQpcZW5ke2FsaWduKn0NCiQkDQoNCg0KKio0LiBBc3N1bXB0aW9ucyoqDQoNCiogIFRoZSBtZWFzdXJlbWVudCBlcnJvcnMgYXJlIHVuY29ycmVsYXRlZCB3aXRoIHRoZSBsYXRlbnQgdmFyaWFibGVzOg0KDQokJA0KICAgIFxiZWdpbnthbGlnbip9DQogICAgRShcYm9sZHN5bWJvbHtcZGVsdGF9fFxib2xkc3ltYm9se1x4aX0pID0gXG1hdGhiZnswfSwgXHF1YWQgRShcYm9sZHN5bWJvbHtcZXBzaWxvbn18XGJvbGRzeW1ib2x7XGV0YX0pID0gXG1hdGhiZnswfQ0KICAgIFxlbmR7YWxpZ24qfQ0KJCQgICAgDQoNCiogVGhlIHN0cnVjdHVyYWwgZGlzdHVyYmFuY2VzIGhhdmUgemVybyBtZWFuIGFuZCBhcmUgdW5jb3JyZWxhdGVkIHdpdGggdGhlIGV4b2dlbm91cyB2YXJpYWJsZXM6DQoNCiQkDQogICAgXGJlZ2lue2FsaWduKn0NCiAgICBFKFxib2xkc3ltYm9se1x6ZXRhfSkgPSBcbWF0aGJmezB9LCBccXVhZCBcdGV4dHtDb3Z9KFxib2xkc3ltYm9se1x6ZXRhfSwgXGJvbGRzeW1ib2x7XHhpfSkgPSBcbWF0aGJmezB9LCBccXVhZCBcdGV4dHtDb3Z9KFxib2xkc3ltYm9se1x6ZXRhfSwgXG1hdGhiZnt3fSkgPSBcbWF0aGJmezB9DQogICAgXGVuZHthbGlnbip9DQokJA0KICAgIA0KKiBUaGUgbWVhc3VyZW1lbnQgZXJyb3JzIGFuZCBzdHJ1Y3R1cmFsIGRpc3R1cmJhbmNlcyBhcmUgbXV0dWFsbHkgdW5jb3JyZWxhdGVkOg0KICAgIA0KJCQNCiAgICBcYmVnaW57YWxpZ24qfQ0KICAgIFx0ZXh0e0Nvdn0oXGJvbGRzeW1ib2x7XGRlbHRhfSwgXGJvbGRzeW1ib2x7XGVwc2lsb259KSA9IFxtYXRoYmZ7MH0sIFxxdWFkIFx0ZXh0e0Nvdn0oXGJvbGRzeW1ib2x7XGRlbHRhfSwgXGJvbGRzeW1ib2x7XHpldGF9KSA9IFxtYXRoYmZ7MH0sIFxxdWFkIFx0ZXh0e0Nvdn0oXGJvbGRzeW1ib2x7XGVwc2lsb259LCBcYm9sZHN5bWJvbHtcemV0YX0pID0gXG1hdGhiZnswfQ0KICAgIFxlbmR7YWxpZ24qfQ0KJCQNCiAgICANCiogVGhlIG1lYXN1cmVtZW50IGVycm9ycyBhcmUgbXV0dWFsbHkgdW5jb3JyZWxhdGVkOg0KDQokJA0KICAgIFxiZWdpbnthbGlnbip9DQogICAgXHRleHR7Q292fShcYm9sZHN5bWJvbHtcZGVsdGF9KSA9IFxib2xkc3ltYm9se1xUaGV0YX1fe1xkZWx0YX0gPSBcdGV4dHtkaWFnfShcdGhldGFfe1xkZWx0YSwxfSwgXGRvdHMsIFx0aGV0YV97XGRlbHRhLDd9KQ0KICAgIFxlbmR7YWxpZ24qfQ0KJCQNCg0KDQokJA0KICAgIFxiZWdpbnthbGlnbip9DQogICAgXHRleHR7Q292fShcYm9sZHN5bWJvbHtcZXBzaWxvbn0pID0gXGJvbGRzeW1ib2x7XFRoZXRhfV97XGVwc2lsb259ID0gXHRleHR7ZGlhZ30oXHRoZXRhX3tcZXBzaWxvbiwxfSwgXGRvdHMsIFx0aGV0YV97XGVwc2lsb24sOX0pDQogICAgXGVuZHthbGlnbip9DQokJA0KDQoqIFRoZSBzdHJ1Y3R1cmFsIGRpc3R1cmJhbmNlcyBoYXZlIGNvdmFyaWFuY2UgbWF0cml4Og0KICAgIA0KJCQNCiAgICBcYmVnaW57YWxpZ24qfQ0KICAgIFx0ZXh0e0Nvdn0oXGJvbGRzeW1ib2x7XHpldGF9KSA9IFxib2xkc3ltYm9se1xQc2l9ID0gDQogICAgXGJlZ2lue2JtYXRyaXh9DQogICAgXHBzaV97MTF9ICYgXHBzaV97MTJ9IFxcDQogICAgXHBzaV97MjF9ICYgXHBzaV97MjJ9DQogICAgXGVuZHtibWF0cml4fQ0KICAgIFxlbmR7YWxpZ24qfQ0KJCQgICAgDQogICAgDQoqIFRoZSBleG9nZW5vdXMgbGF0ZW50IHZhcmlhYmxlcyBoYXZlIGNvdmFyaWFuY2UgbWF0cml4Og0KDQokJA0KICAgIFxiZWdpbnthbGlnbip9DQogICAgXHRleHR7Q292fShcYm9sZHN5bWJvbHtceGl9KSA9IFxib2xkc3ltYm9se1xQaGl9ID0gDQogICAgXGJlZ2lue2JtYXRyaXh9DQogICAgXHBoaV97MTF9ICYgXHBoaV97MTJ9IFxcDQogICAgXHBoaV97MjF9ICYgXHBoaV97MjJ9DQogICAgXGVuZHtibWF0cml4fQ0KICAgIFxlbmR7YWxpZ24qfQ0KJCQNCg0KKiBUaGUgZXhvZ2Vub3VzIG9ic2VydmVkIHZhcmlhYmxlcyBoYXZlIGNvdmFyaWFuY2UgbWF0cml4Og0KDQokJA0KICAgIFxiZWdpbnthbGlnbip9DQogICAgXHRleHR7Q292fShcbWF0aGJme3d9KSA9IFxib2xkc3ltYm9se1xQaGl9X3cNCiAgICBcZW5ke2FsaWduKn0NCiQkDQoNCg0KKiBBbGwgdmFyaWFibGVzIGFyZSBtdWx0aXZhcmlhdGUgbm9ybWFsbHkgZGlzdHJpYnV0ZWQuDQoNCg0KKio1LiBJbXBsaWVkIENvdmFyaWFuY2UgTWF0cml4KioNCg0KTGV0ICRcYm9sZHN5bWJvbHtcdGhldGF9JCByZXByZXNlbnQgYWxsIG1vZGVsIHBhcmFtZXRlcnMuIFRoZSBpbXBsaWVkIGNvdmFyaWFuY2UgbWF0cml4IG9mIHRoZSBvYnNlcnZlZCB2YXJpYWJsZXMgJFxtYXRoYmZ7en0gPSAoXG1hdGhiZnt4fV5ULCBcbWF0aGJme3l9XlQsIFxtYXRoYmZ7d31eVCleVCQgaXM6DQoNCiQkDQpcYmVnaW57YWxpZ24qfQ0KXGJvbGRzeW1ib2x7XFNpZ21hfShcYm9sZHN5bWJvbHtcdGhldGF9KSA9IA0KXGJlZ2lue2JtYXRyaXh9DQpcYm9sZHN5bWJvbHtcU2lnbWF9X3t4eH0oXGJvbGRzeW1ib2x7XHRoZXRhfSkgJiBcYm9sZHN5bWJvbHtcU2lnbWF9X3t4eX0oXGJvbGRzeW1ib2x7XHRoZXRhfSkgJiBcYm9sZHN5bWJvbHtcU2lnbWF9X3t4d30oXGJvbGRzeW1ib2x7XHRoZXRhfSkgXFwNClxib2xkc3ltYm9se1xTaWdtYX1fe3l4fShcYm9sZHN5bWJvbHtcdGhldGF9KSAmIFxib2xkc3ltYm9se1xTaWdtYX1fe3l5fShcYm9sZHN5bWJvbHtcdGhldGF9KSAmIFxib2xkc3ltYm9se1xTaWdtYX1fe3l3fShcYm9sZHN5bWJvbHtcdGhldGF9KSBcXA0KXGJvbGRzeW1ib2x7XFNpZ21hfV97d3h9KFxib2xkc3ltYm9se1x0aGV0YX0pICYgXGJvbGRzeW1ib2x7XFNpZ21hfV97d3l9KFxib2xkc3ltYm9se1x0aGV0YX0pICYgXGJvbGRzeW1ib2x7XFNpZ21hfV97d3d9KFxib2xkc3ltYm9se1x0aGV0YX0pDQpcZW5ke2JtYXRyaXh9DQpcZW5ke2FsaWduKn0NCiQkDQoNCndoZXJlOg0KDQokJA0KXGJlZ2lue2FsaWduKn0NClxib2xkc3ltYm9se1xTaWdtYX1fe3h4fShcYm9sZHN5bWJvbHtcdGhldGF9KSAmPSBcYm9sZHN5bWJvbHtcTGFtYmRhfV94IFxib2xkc3ltYm9se1xQaGl9IFxib2xkc3ltYm9se1xMYW1iZGF9X3heVCArIFxib2xkc3ltYm9se1xUaGV0YX1fe1xkZWx0YX0gXFwNClxib2xkc3ltYm9se1xTaWdtYX1fe3l5fShcYm9sZHN5bWJvbHtcdGhldGF9KSAmPSBcYm9sZHN5bWJvbHtcTGFtYmRhfV95IChcbWF0aGJme0l9LVxtYXRoYmZ7Qn0pXnstMX0gKFxib2xkc3ltYm9se1xHYW1tYX0gXGJvbGRzeW1ib2x7XFBoaX0gXGJvbGRzeW1ib2x7XEdhbW1hfV5UICsgXGJvbGRzeW1ib2x7XEdhbW1hfV93IFxib2xkc3ltYm9se1xQaGl9X3cgXGJvbGRzeW1ib2x7XEdhbW1hfV93XlQgKyBcYm9sZHN5bWJvbHtcUHNpfSkgWyhcbWF0aGJme0l9LVxtYXRoYmZ7Qn0pXnstMX1dXlQgXGJvbGRzeW1ib2x7XExhbWJkYX1feV5UICsgXGJvbGRzeW1ib2x7XFRoZXRhfV97XGVwc2lsb259IFxcDQpcYm9sZHN5bWJvbHtcU2lnbWF9X3t3d30oXGJvbGRzeW1ib2x7XHRoZXRhfSkgJj0gXGJvbGRzeW1ib2x7XFBoaX1fdyBcXA0KXGJvbGRzeW1ib2x7XFNpZ21hfV97eHl9KFxib2xkc3ltYm9se1x0aGV0YX0pICY9IFxib2xkc3ltYm9se1xMYW1iZGF9X3ggXGJvbGRzeW1ib2x7XFBoaX0gXGJvbGRzeW1ib2x7XEdhbW1hfV5UIFsoXG1hdGhiZntJfS1cbWF0aGJme0J9KV57LTF9XV5UIFxib2xkc3ltYm9se1xMYW1iZGF9X3leVCBcXA0KXGJvbGRzeW1ib2x7XFNpZ21hfV97eHd9KFxib2xkc3ltYm9se1x0aGV0YX0pICY9IFxib2xkc3ltYm9se1xMYW1iZGF9X3ggXHRleHR7Q292fShcYm9sZHN5bWJvbHtceGl9LCBcbWF0aGJme3d9KSBcXA0KXGJvbGRzeW1ib2x7XFNpZ21hfV97eXd9KFxib2xkc3ltYm9se1x0aGV0YX0pICY9IFxib2xkc3ltYm9se1xMYW1iZGF9X3kgKFxtYXRoYmZ7SX0tXG1hdGhiZntCfSleey0xfSAoXGJvbGRzeW1ib2x7XEdhbW1hfSBcdGV4dHtDb3Z9KFxib2xkc3ltYm9se1x4aX0sIFxtYXRoYmZ7d30pICsgXGJvbGRzeW1ib2x7XEdhbW1hfV93IFxib2xkc3ltYm9se1xQaGl9X3cpDQpcZW5ke2FsaWduKn0NCiQkDQoNCioqNi4gTGlrZWxpaG9vZCBGdW5jdGlvbioqDQoNCkFzc3VtaW5nIG11bHRpdmFyaWF0ZSBub3JtYWxpdHkgb2YgdGhlIG9ic2VydmVkIHZhcmlhYmxlcyAkXG1hdGhiZnt6fSBcc2ltIE4oXGJvbGRzeW1ib2x7XG11fSwgXGJvbGRzeW1ib2x7XFNpZ21hfShcYm9sZHN5bWJvbHtcdGhldGF9KSkkLCB0aGUgbGlrZWxpaG9vZCBmdW5jdGlvbiBmb3IgYSBzYW1wbGUgb2YgJG4kIGluZGVwZW5kZW50IG9ic2VydmF0aW9ucyBpczoNCg0KJCQNClxiZWdpbnthbGlnbip9DQpMKFxib2xkc3ltYm9se1x0aGV0YX0pICY9IFxwcm9kX3tpPTF9Xm4gKDJccGkpXnstcC8yfSB8XGJvbGRzeW1ib2x7XFNpZ21hfShcYm9sZHN5bWJvbHtcdGhldGF9KXxeey0xLzJ9IFxleHBcbGVmdFstXGZyYWN7MX17Mn0oXG1hdGhiZnt6fV9pIC0gXGJvbGRzeW1ib2x7XG11fSleVCBcYm9sZHN5bWJvbHtcU2lnbWF9KFxib2xkc3ltYm9se1x0aGV0YX0pXnstMX0gKFxtYXRoYmZ7en1faSAtIFxib2xkc3ltYm9se1xtdX0pXHJpZ2h0XQ0KXGVuZHthbGlnbip9DQokJA0KDQp3aGVyZSAkcCA9IDcgKyA5ICsgNSA9IDIxJCBpcyB0aGUgdG90YWwgbnVtYmVyIG9mIG9ic2VydmVkIHZhcmlhYmxlcy4NCg0KVGhlIGxvZy1saWtlbGlob29kIGZ1bmN0aW9uIGlzOg0KDQokJA0KXGJlZ2lue2FsaWduKn0NClxlbGwoXGJvbGRzeW1ib2x7XHRoZXRhfSkgJj0gLVxmcmFje25wfXsyfSBcbG9nKDJccGkpIC0gXGZyYWN7bn17Mn0gXGxvZ3xcYm9sZHN5bWJvbHtcU2lnbWF9KFxib2xkc3ltYm9se1x0aGV0YX0pfCBcXA0KJlxxdWFkIC0gXGZyYWN7MX17Mn0gXHN1bV97aT0xfV5uIChcbWF0aGJme3p9X2kgLSBcYm9sZHN5bWJvbHtcbXV9KV5UIFxib2xkc3ltYm9se1xTaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSleey0xfSAoXG1hdGhiZnt6fV9pIC0gXGJvbGRzeW1ib2x7XG11fSkNClxlbmR7YWxpZ24qfQ0KJCQNCg0KRm9yIGVzdGltYXRpb24sIHdlIHR5cGljYWxseSB1c2UgdGhlIGRpc2NyZXBhbmN5IGZ1bmN0aW9uOg0KDQokJA0KXGJlZ2lue2FsaWduKn0NCkZfe01MfShcYm9sZHN5bWJvbHtcdGhldGF9KSAmPSBcbG9nfFxib2xkc3ltYm9se1xTaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSl8ICsgXHRleHR7dHJ9KFxtYXRoYmZ7U30gXGJvbGRzeW1ib2x7XFNpZ21hfShcYm9sZHN5bWJvbHtcdGhldGF9KV57LTF9KSAtIFxsb2d8XG1hdGhiZntTfXwgLSBwDQpcZW5ke2FsaWduKn0NCiQkDQoNCndoZXJlICRcbWF0aGJme1N9JCBpcyB0aGUgc2FtcGxlIGNvdmFyaWFuY2UgbWF0cml4Lg0KDQoqKjcuIFBhcmFtZXRlcnMgdG8gRXN0aW1hdGUqKg0KDQpUaGUgbW9kZWwgcGFyYW1ldGVycyBpbmNsdWRlOg0KDQoNCiogRmFjdG9yIGxvYWRpbmdzOiAkXGxhbWJkYV97aWp9JCBpbiAkXGJvbGRzeW1ib2x7XExhbWJkYX1feCQgYW5kICRcYm9sZHN5bWJvbHtcTGFtYmRhfV95JA0KKiBTdHJ1Y3R1cmFsIGNvZWZmaWNpZW50czogJFxiZXRhX3tpan0kIGluICRcbWF0aGJme0J9JCwgJFxnYW1tYV97aWp9JCBpbiAkXGJvbGRzeW1ib2x7XEdhbW1hfSQsICRcZ2FtbWFfe2lqfV53JCBpbiAkXGJvbGRzeW1ib2x7XEdhbW1hfV93JA0KKiBWYXJpYW5jZXMgYW5kIGNvdmFyaWFuY2VzOiAkXHBoaV97aWp9JCBpbiAkXGJvbGRzeW1ib2x7XFBoaX0kLCAkXHBzaV97aWp9JCBpbiAkXGJvbGRzeW1ib2x7XFBzaX0kLCAkXHBoaV97dyxpan0kIGluICRcYm9sZHN5bWJvbHtcUGhpfV93JA0KKiAgTWVhc3VyZW1lbnQgZXJyb3IgdmFyaWFuY2VzOiAkXHRoZXRhX3tcZGVsdGEsaX0kIGluICRcYm9sZHN5bWJvbHtcVGhldGF9X3tcZGVsdGF9JCwgJFx0aGV0YV97XGVwc2lsb24saX0kIGluICRcYm9sZHN5bWJvbHtcVGhldGF9X3tcZXBzaWxvbn0kDQoNCg0KDQpUeXBpY2FsbHksIHdlIHNldCBvbmUgbG9hZGluZyBwZXIgbGF0ZW50IHZhcmlhYmxlIHRvIDEgZm9yIGlkZW50aWZpY2F0aW9uLg0KDQoqKjguIE1vZGVsIElkZW50aWZpY2F0aW9uKioNCg0KVGhlIG1vZGVsIGlzIGlkZW50aWZpZWQgaWY6DQoNCiogIEVhY2ggbGF0ZW50IHZhcmlhYmxlIGhhcyBhdCBsZWFzdCAzIGluZGljYXRvcnMgKHNhdGlzZmllZCkNCiogIFRoZSBzY2FsZSBvZiBlYWNoIGxhdGVudCB2YXJpYWJsZSBpcyBzZXQgYnkgZml4aW5nIG9uZSBsb2FkaW5nIHRvIDENCiogIFRoZSBtb2RlbCBtZWV0cyB0aGUgb3JkZXIgY29uZGl0aW9uIGFuZCByYW5rIGNvbmRpdGlvbiBmb3IgaWRlbnRpZmljYXRpb24NCg0KDQoNCg0KDQo=